c - 使用 Assembly 在 C 中添加

标签 c gcc assembly x86 add

我非常擅长 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;
}

另外,我相信你不理解“=$”这个概念。据我所知,你只是在那里写变量名,但它不是这样工作的。从网站上看,约束约束(众所周知)如下:

  1. "m": 内存操作数是允许的,具有任何类型的地址 机器支持一般。
  2. "o": 内存操作数是允许的,但是 仅本地址可偏移时。即,将一个小的偏移量添加到 address 给出一个有效的地址。
  3. "V": 一个内存操作数不是 抵消。换句话说,任何适合 m' 的东西 约束但不是 o'约束。
  4. "i": 一个立即数 操作数(一个具有常量值的)是允许的。这包括象征性的 其值仅在汇编时才知道的常量。
  5. “n”: 允许使用具有已知数值的立即整数操作数。 许多系统不支持操作数的汇编时常量 不到一个字宽。这些操作数的约束应该使用'n' 而不是“我”。
  6. "g": 任何寄存器、内存或立即整数 操作数是允许的,除了不通用的寄存器 注册。

有关更多示例和其他限制,请参阅该站点。希望这有帮助! :)

关于c - 使用 Assembly 在 C 中添加,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16106430/

相关文章:

gcc - CUDA 和 gcc 兼容性问题

c++ - 使用 SIMD 指令执行任意 128/256/512 位排列的最快方法是什么?

c - c 中的段错误(核心转储)(将文本发送到数组)

gcc 输出的目标文件是否可以在具有相同选项的相同源的编译之间变化?

android - 如何从已编译的二进制文件 (.so) 中删除字符串

c - 为什么 GCC 保留空函数?

c - 我在什么环境下打开 prj/dtp 文件?

c - 读取不一致的文件

assembly - BIOS 中断时光标不会移动(x86 汇编/NASM)

二进制中的常量符号