c - 内联汇编未知

标签 c gcc assembly inline-assembly att

static inline void *__memset(void *s, char c, size_t n) {
int d0, d1;
asm volatile (
    "rep; stosb;"
    : "=&c" (d0), "=&D" (d1)
    : "0" (n), "a" (c), "1" (s)
    : "memory");
return s;
}

“d0”和“d1”有什么用?能否请您完整解释所有代码?谢谢!

最佳答案

您需要了解 gcc 扩展内联 asm 格式:

  • 第一部分是实际组装。在这种情况下,只有 2 条指令
  • 第二部分指定输出约束,第三部分指定输入约束。第四部分指定程序集将破坏内存

输出

  • "=&c" 将 d0 与 ecx 寄存器相关联并将其标记为只写。 &表示在代码结束前可以修改
  • "=&D" 意思是一样的,对于edi寄存器

输入

  • "0"(n) 将 n 与第一个提到的寄存器相关联。在你的情况下,使用 ecx
  • "a"(c) 将 c 与 eax 相关联
  • "1"(s) 将 s 与 edi 相关联

程序集

就是这样。重复此 ecx 次(n 次):将 eax (c) 存储到 edi (s),然后递增它。


那么,为什么未使用 d0d1 ?我不确定。我也认为它们在这种情况下没有用,整个输出部分可以留空但我认为不可能在输入约束中指定“可写”和“早期-clobbered”。所以我认为 d0d1 是为了让 & 成为可能。

我会尝试这样写:

asm volatile (
    "rep\n"
    "stosb\n"
    :
    : "c" (n), "a" (c), "D" (s)
    : "%ecx", "%edi", "memory"
);

关于c - 内联汇编未知,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9787861/

相关文章:

c - 如何用C语言求解100^1000?

支持mocking嵌套函数的C单元测试框架

c++ - 识别自动生成的成员函数

c - 在 C 的程序集中使用标签

assembly - 从 x86 汇编创建更小的指令集

assembly - 为什么热点生成的编译方法在执行前将 eax 存储在堆栈中?

c - getutent 和 Linux 计时器问题

c - 如何解决 undefined reference

linux - 如何更改ld.so中的默认路径

c - C 数组的对齐方式 - 数组元素的对齐方式大于元素大小