【发布时间】:2014-07-19 13:07:03
【问题描述】:
我正在尝试编写一个内联汇编函数来交换两个值。(我正在使用扩展的 ASM 格式)
此代码有效:
#include <stdio.h>
void Exchange(int *x, int *y)
{
printf("In Exchange function: Before exchange x is: %d\n",*x);
printf("In Exchange function: Before exchange y is: %d\n",*y);
asm("xchg %%eax,%%edx\n\t" \
:"+a"(*x),"+d"(*y));
printf("In Exchange function: After exchange x is: %d\n",*x);
printf("In Exchange function: After exchange y is: %d\n",*y);
}
int main()
{
int x=20;
int y=30;
printf("In main: Before exchange x is: %d\n",x);
printf("In main: Before exchange y is: %d\n",y);
Exchange(&x,&y);
printf("In main: After exchange x is: %d\n",x);
printf("In main: After exchange y is: %d\n",y);
return 0;
}
但是当我尝试像下面这样以完整的程序集编写它时,我得到了分段错误(核心转储)错误。
void Exchange(int *x, int *y)
{
asm("subl $8,%%esp\n\t" \
"movl %%eax,4(%%esp)\n\t" \
"movl %%edx,(%%esp)\n\t" \
"call printf\n\t" \
"addl $8,%%esp\n\t" \
"xchg %%eax,%%edx\n\t" \
"subl $8,%%esp\n\t" \
"movl %%eax,4(%%esp)\n\t" \
"movl %%edx,(%%esp)\n\t" \
"call printf\n\t" \
"addl $8,%%esp\n\t" \
:"+a"(*x),"+d"(*y));
}
int main()
{
int x=20;
int y=30;
printf("In main: Before exchange x is: %d\n",x);
printf("In main: Before exchange y is: %d\n",y);
Exchange(&x,&y);
printf("In main: After exchange x is: %d\n",x);
printf("In main: After exchange y is: %d\n",y);
return 0;
}
我们不能在汇编部分使用 printf 函数吗?
【问题讨论】:
-
查看您的第一个代码示例,是否有某些原因需要强制使用特定的 eax 和 edx 寄存器?为什么不使用 asm("xchg %0,%1" :"+r"(*x),"+r"(*y)) 让编译器选择最有效的?或者如果你真的想看人的脑袋爆炸,试试 asm("" : "=r"(*x),"=r"(*y) : "1" (*x), "0" (*y) )。看,没有代码!但它仍然有效。
标签: c assembly inline-assembly