免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
楼主: zylthinking
打印 上一主题 下一主题

[其他] 这是什么意思 [复制链接]

论坛徽章:
3
15-16赛季CBA联赛之山东
日期:2016-10-30 08:47:3015-16赛季CBA联赛之佛山
日期:2016-12-17 00:06:31CU十四周年纪念徽章
日期:2017-12-03 01:04:02
1 [报告]
发表于 2012-10-12 23:24 |显示全部楼层
果断要从调用惯例/约定说起. 这个约定通常是ABI的一部分.

调用惯例/约定规定了, 当一个函数(caller)调用其他函数(被调用函数, callee)时, callee不应当修改/覆盖caller调用callee后要用到的哪些寄存器.
即:
  1. void callee(void)
  2. {
  3.     ...
  4. }

  5. void caller(void)
  6. {
  7.     // [1] ...
  8.     callee();
  9.     // [2] ...
  10. }
复制代码
ABI的调用惯例/约定保证, 在caller调用callee之前(即[1])处, 与caller调用callee之后(即[2])处, 哪一些寄存器的内容是确保不会改变的.比如x86, 一般规定ebx, esi, edi都是调用callee前后不会改变的 -- 亦即, 如果callee修改了ebx, or esi, edi, 那么callee在修改之前要先将其保存到栈上, 然后修改, 修改完返回到调用方之前要恢复ebx, or esi, edi.
那么, 言外之意也就是说, 还有一部分寄存器的内容是会被改变的. 比如x86, eax, ecx, edx都是调用惯例不保证的. 既然调用惯例不保证caller调用callee前后其值不变, 那么caller在调用callee之前, 应当自己先把寄存器eax, ecx, edx都保存到栈上, 等调用完毕, 又自己恢复它们的值. 那么, eax, ecx, edx即被称为 call-clobbered -- 调用函数后不保证其内容和调用前不变. 即是有可能被破坏的意思.
请注意 -- 这个调用惯例/约定是规定编译器该怎么做.即, 根据这个约定, 编译器知道caller调用前应该保存哪些寄存器, 调用后恢复哪些寄存器, 同样, 编译器也知道callee应该在对哪些寄存器进行修改前要先保存, 返回前要先恢复.

回到LZ的例子. 前面一段大意是, 嵌入式汇编中, 因为寄存器多是gcc自动分配, 没有某种强制的约束字, 于是当你想自己强制约束寄存器和变量的对应时怎样怎样云云.
  1. register int *p1 asm("r0") = ...; // op1
  2. register int *p2 asm("r1") = ...; // op2
  3. register int *result asm("r0");
复制代码
这段代码中, op1是无所谓的. 就算op1调用了函数, 这个函数修改了某些寄存器的值, 但是编译器和ABI会保证, 你调用前后寄存器的值都是一致的 -- 反正不是调用方 保存/恢复 就是被调用方 保存/恢复.
但是op2就不同了. 原因就是写代码的人已经擅自强制使用了寄存器(例子中是r0). C语言和编译器 -- 没办法/或者很难? 约束/预知 Coder的这个行为. 因为Coder擅自使用了寄存器, 那么责任就应该由Coder自己负责, 编译器不知道应该调用前保存哪个, 调用后恢复哪个. 即, 如果op2是一个函数调用, 那么显然op2中会破坏一些寄存器, 本来编译器根据ABI是知道哪些应该恢复的, 但是Coder又使用了, 所以, 这个责任Coder自己负责, 就是这个意思(ps, 一般的C语言的赋值操作怎么可能调函数, 不是mov指令就完事的么. C++重载赋值操作符了才得那么干. 当然C语言的结构体变量赋值倒也不是一个mov万事那么简单, memcpy也就行了. 那个op2是指代 '...', 即starwing83解释的那样, op2调函数了).

基本上, 我认为starwing83的解释也是对的. 我只是先啰嗦了调用约定(r0, r1神马的果断是ARM吗. 那么就是APCS了).

==========================================
至于第二个, 我认为也应该从调用约定的出发点去理解. 基本上, call-Clobber list中的寄存器就是不适宜使用的, 否则Coder自己care.
==========================================

呃... 当然我可能根本没理解或者解释错了. 那么LZ砖轻拍.

论坛徽章:
3
15-16赛季CBA联赛之山东
日期:2016-10-30 08:47:3015-16赛季CBA联赛之佛山
日期:2016-12-17 00:06:31CU十四周年纪念徽章
日期:2017-12-03 01:04:02
2 [报告]
发表于 2012-10-13 17:53 |显示全部楼层
本帖最后由 captivated 于 2012-10-13 20:17 编辑

果然还是觉得太失水准了. 编辑掉编辑掉...

论坛徽章:
3
15-16赛季CBA联赛之山东
日期:2016-10-30 08:47:3015-16赛季CBA联赛之佛山
日期:2016-12-17 00:06:31CU十四周年纪念徽章
日期:2017-12-03 01:04:02
3 [报告]
发表于 2012-10-13 18:08 |显示全部楼层
starwing83 发表于 2012-10-13 16:48
回复 8# zylthinking

一些东西很明显他用一种”你懂的“口气对你说  = =太猥琐了……


同感同感. 我的兴趣目前是gas. 哈, 叔叔我要发掘出GNU许许多多猥琐的地方, 让后将其公诸于世...

论坛徽章:
3
15-16赛季CBA联赛之山东
日期:2016-10-30 08:47:3015-16赛季CBA联赛之佛山
日期:2016-12-17 00:06:31CU十四周年纪念徽章
日期:2017-12-03 01:04:02
4 [报告]
发表于 2012-10-13 18:28 |显示全部楼层
回复 14# starwing83


    哦。

    asm("指令部": 输出部: 输入部: 破坏部);

    “指令部”即template, 输出部即output, 输入部即input, 破坏部即clobber description

    翻译LZ的东西时, 当时我真没敢确定那个clobber description就是嵌入汇编的破坏部...

论坛徽章:
3
15-16赛季CBA联赛之山东
日期:2016-10-30 08:47:3015-16赛季CBA联赛之佛山
日期:2016-12-17 00:06:31CU十四周年纪念徽章
日期:2017-12-03 01:04:02
5 [报告]
发表于 2012-10-13 18:33 |显示全部楼层
晕。那我那个翻译要赶快编辑掉编辑掉... 哈哈,算了。给LZ和starwing83道一声献丑了...
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP