如何访问和更改c x86 AT& T内联汇编

时间:2018-05-19 15:20:07

标签: c assembly x86 inline-assembly cpu-registers

我在解决学校练习时遇到问题,我应该使用内联汇编更改c中的char数组。在这种情况下,将“ahoy”更改为“aXoy”,但我遇到了分段错误。这是我的代码:

 #include <stdio.h>

    int main() {
        char string[] = "ahoy";
        __asm__ volatile (
                "mov %0, %%eax;"
                "movb $'X', 1(%%eax);"
                : "=m"(string) : "0"(string) : "memory", "eax");
        printf("%s\n", string);
        return 0
    }

用这个:"mov %0, %%eax;"我试图在寄存器中存储数组的地址

然后用这个:"movb $'X', 1(%%eax);"我想将字节'X'存储在由(%% eax)指向的位置,偏移1个字节(char),

我将字符串作为输出和输入,以及“内存”,“eax”在clobber中,因为我正在修改它们。我的代码出了什么问题?

1 个答案:

答案 0 :(得分:1)

使用gcc -S而不是-c查看编译器的程序集输出,您应该看到错误。 "m"约束生成用于访问与其关联的对象的内存引用表达式,而不是包含其地址的寄存器。因此它会扩展为(%ecx),而不是%ecx,第一个mov将从string加载4个字节,而不是string的地址,进入eax

解决此问题的一种方法是使用寄存器约束"r"(string)

或者,您可以将mov替换为lealea %0, %%eax

您的代码还存在其他问题,例如无用的临时/ clobber注册eax,但它们不应使其无法正常工作。