我非常擅长 C,而不是汇编,但出于兴趣,我想使用 gcc 在 C 中进行一些工作。问题是我的程序要么给出了一些愚蠢的数字,要么崩溃了。
unsigned sadd32(unsigned a, unsigned b)
{
unsigned c = 0;
__asm__("movl %%eax, %0" : "=a"(a));
__asm__("addl %%eax, %0" : "=b"(b));
__asm__("movl %edx, 0xffffffff");
__asm__("cmovc %eax, %edx");
__asm__("movl %0, %%eax" : "=c"(c));
return c;
}
我确定我做了一些愚蠢的事情,如果有人能看出来的话?? ;)
最佳答案
#include <stdio.h>
#include <stdlib.h>
unsigned sadd32(unsigned a, unsigned b)
{
unsigned c = 0;
__asm__ ("movl %2, %%eax\n\t"
"addl %1, %%eax\n\t"
"movl %%eax, %0\n\t"
:"=r"(c)
:"r"(a),"r"(b)
:"%eax"
);
return c;
}
int main()
{
unsigned int a=3,b=5;
printf("The sum of %u and %u is %u\n",a,b,sadd32(a,b));
return 0;
}
引用:http://www.ibiblio.org/gferg/ldp/GCC-Inline-Assembly-HOWTO.html
据我所知,您的代码存在一些缺陷::
unsigned sadd32(unsigned a, unsigned b)
{
unsigned c = 0;
__asm__("movl %%eax, %0" : "=a"(a));
__asm__("addl %%eax, %0" : "=b"(b));
__asm__("movl %edx, 0xffffffff"); /* this here, you are specifying a manual location, may not be accessible or valid */
__asm__("cmovc %eax, %edx"); /* resulting in its error */
__asm__("movl %0, %%eax" : "=c"(c));
return c;
}
另外,我相信你不理解“=$”这个概念。据我所知,你只是在那里写变量名,但它不是这样工作的。从网站上看,约束约束(众所周知)如下:
- "m": 内存操作数是允许的,具有任何类型的地址 机器支持一般。
- "o": 内存操作数是允许的,但是 仅本地址可偏移时。即,将一个小的偏移量添加到 address 给出一个有效的地址。
- "V": 一个内存操作数不是
抵消。换句话说,任何适合
m' 的东西 约束但不是
o'约束。 - "i": 一个立即数 操作数(一个具有常量值的)是允许的。这包括象征性的 其值仅在汇编时才知道的常量。
- “n”: 允许使用具有已知数值的立即整数操作数。 许多系统不支持操作数的汇编时常量 不到一个字宽。这些操作数的约束应该使用'n' 而不是“我”。
- "g": 任何寄存器、内存或立即整数 操作数是允许的,除了不通用的寄存器 注册。
有关更多示例和其他限制,请参阅该站点。希望这有帮助! :)
关于c - 使用 Assembly 在 C 中添加,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16106430/