One*_*Arb 3 assembly gcc inline-assembly i386
在我的计算机上,编译的可执行文件省略了在循环顶部执行"mov%2,%% ax"
当"添加%1,%% ax"取消注释时.
有人要进行双重检查或评论?
#include <stdio.h>
int main() {
short unsigned result, low ,high;
low = 0;
high = 1;
__asm__ (
"movl $10, %%ecx \n\t"
"loop: mov %2, %%ax \n\t"
// "add %1, %%ax \n\t" // uncomment and result = 10
"mov %%ax, %0 \n\t"
"subl $1, %%ecx \n\t"
"jnz loop"
: "=r" (result)
: "r" (low) , "r" (high)
: "%ecx" ,"%eax" );
printf("%d\n", result);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
跟随生成的程序集
movl $1, %esi
xorl %edx, %edx
/APP
movl $10 ,%ecx
loop: mov %si, %ax
mov %dx, %bx
add %bx, %ax
mov %ax, %dx
subl $1, %ecx
jnz loop
/NO_APP
Run Code Online (Sandbox Code Playgroud)
感谢Jester的解决方案:
: "=&r" (result) // early clober modifier
Run Code Online (Sandbox Code Playgroud)
GCC内联汇编是高级编程,存在很多陷阱.确保您确实需要它,并且不能使用独立组装模块或使用内在函数的C代码替换它.或矢量支持.
如果你坚持内联汇编,你应该准备至少查看生成的汇编代码并尝试从中找出任何错误.显然,编译器不会省略您写入asm块的任何内容,它只是替换参数.如果查看生成的代码,您可能会看到如下内容:
add %dx, %ax
mov %ax, %dx
Run Code Online (Sandbox Code Playgroud)
显然编译器选择dx了参数0和1.允许这样做,因为默认情况下它假定在写入任何输出之前消耗输入参数.要表明情况并非如此,您必须为输出操作数使用早期clobber修饰符,因此它看起来像"=&r".
PS:即使内联汇编似乎有效,它也可能有隐藏的问题,当编译器碰巧做出其他选择时,这些问题会让你感到痛苦.你应该真的避免它.
| 归档时间: |
|
| 查看次数: |
314 次 |
| 最近记录: |