首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >内联asm未知

内联asm未知
EN

Stack Overflow用户
提问于 2012-03-20 21:36:44
回答 2查看 667关注 0票数 3
代码语言:javascript
复制
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”是用来做什么的?你能完整地解释一下所有的代码吗?谢谢!

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-03-20 23:58:39

"d0“和"d1”是用来做什么的?

实际上,它表示%ecx%edi (假设32位)的最终值分别存储在d0d1中。这有几个目的:

它让编译器知道,作为输出,这些寄存器被有效地销毁了。通过将它们分配给临时变量,优化编译器还知道不需要实际执行“存储”操作。

"=&“将这些指定为早期截断操作数。它们可能会在所有输入被使用之前被写入。因此,如果编译器可以自由选择输入寄存器,它就不应该将这两个寄存器别名。

对于%ecx来说,这在技术上不是必需的,因为它被显式地命名为输入:"0" (n) -本例中的“rep”计数。我也不确定这对于%edi是不是必要的,因为在使用输入"1" (s)和执行指令之前,它不能被更新。同样,由于它被显式命名为输入,编译器不能自由选择另一个寄存器。简而言之,"=&“在这里不会有任何影响,但它不会做任何事情。

由于"a" (c)指定了一个设置为(c)的仅用于输入的寄存器%eax,编译器可能会认为%eax在'asm‘之后仍然保留这个值-- "rep; stosb;"确实就是这种情况。

"memory"指定可以以编译器不知道的方式修改内存-在本例中,编译器将从(r)开始的(n)字节设置为值(c) -假设方向标志被清除,它应该清除方向标志。这确实具有强制重新加载值的效果,因为编译器不能再假设寄存器反映它们应该反映的内存值。这不会有什么坏处,而且对于一般情况下的memset来说,可能有必要保证它的安全性,但它通常是过度杀伤力。

编辑:输入操作数不能与压缩操作数重叠。将某些内容指定为仅限输入的 clobbered是没有意义的。我认为编译器不允许这样做,即使这样,使用模棱两可的规范也不是明智之举。从手册中:

您不能以与输入或输出操作数重叠的方式编写clobber描述。例如,如果您在clobber列表中提到寄存器,则可能没有一个操作数描述具有一个成员的寄存器类。

回顾一些旧的答案,我想我应该添加一个链接,指向优秀的 GCC内联ASM教程。这篇文章建立在前几节的基础上,不像gcc手册,它最好被描述为“参考”,并不真正适合任何类型的结构化学习。

票数 1
EN

Stack Overflow用户

发布于 2012-03-20 21:53:22

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

  • 第一部分是实际的装配。在这种情况下,只有2个instructions
  • The,第二部分指定输出约束,第三部分指定输入约束。第四部分指定程序集将占用内存

输出

  • "=&c"将d0与ecx寄存器关联,并将其标记为只写。对于edi寄存器

&意味着可以在edi结束之前对其进行修改

输入

  • "0" (n)将n与前面提到的寄存器关联。在您的示例中,使用ecx
  • "a" (c)关联c与eax
  • "1" (s)关联s与edi

组件

现在你就知道了。重复此ecx (n次):将eax (c)存储到edi中,然后递增它。

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

我会试着这样写:

代码语言:javascript
复制
asm volatile (
    "rep\n"
    "stosb\n"
    :
    : "c" (n), "a" (c), "D" (s)
    : "%ecx", "%edi", "memory"
);
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/9787861

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档