c - 如何在 c x86 AT&T 内联汇编中访问和更改 char 数组

标签 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字节(字符),

我有字符串作为输出和输入,并且在 clobber 中有 "memory","eax"因为我正在修改两者。我的代码有什么问题?

最佳答案

使用gcc -S 而不是-c 来查看编译器的汇编输出,您应该可以看出哪里出了问题。 "m" 约束生成用于访问与其关联的对象的内存引用表达式,而不是包含其地址的寄存器。所以它将扩展为类似(%ecx),而不是%ecx,第一个mov将从string加载4个字节,而不是 string 的地址,放入 eax

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

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

您的代码还有其他问题,例如无用的临时/破坏寄存器 eax,但它们不应该阻止它正常工作。

关于c - 如何在 c x86 AT&T 内联汇编中访问和更改 char 数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50426786/

相关文章:

c++ - 设置位是否与同一个字上的并发其他位集发生冲突?

c++ - opengl 位于何处(gpu 软件或操作系统)?

x86 - 有没有一种有效的方法来使用SIMD内部函数获取SIMD寄存器中的第一个非零元素?

c - qsort 函数指针的类型转换

c++ - 清除 __m128i 的高位字节

c - 双指针和字符

c# - 尝试在 C# 中创建基本编译器,获取访问冲突错误

assembly - INT 13, 2 在尝试从软盘驱动器读取扇区时卡在 x86 实模式上

c - 在 AVX2 中屏蔽单个位的最佳方法?

c - Modbus 主从通信