似乎无法将%ES添加到clobberlist(内联汇编,GCC)

我正在通过Micheal Abrash的图形编程黑皮书(顺便说一句,我非常喜欢,我强烈推荐它),所以我正在使用的示例代码已经很老了。 但是,我不明白问题所在:

__asm__(
    //Some setup code here
    "movl %%esi, %%edi;"
    "movw %%ds, %%es;"
    //A whole bunch more assembly code in between
    "divloop:"
    "lodsw;"
    "divl %%ebx;"
    "stosw;"
    "loop divloop;"
    //And a little more code here
    : "=r" (ret)
    : "0" (ret) /*Have to do this for some reason*/, "b" (div), "c" (l), "S" (p)
    : "%edi", "%es"
);
  • l变量是一个unsigned int, p变量是一个char *。 lp指向的字符串长度的字节数。 div是除数,是一个无符号整数。 ret是函数的返回值(一个无符号整数),并在内部将其设置为组合块,作为除法的其余部分。
  • 我收到的错误消息是“错误:'asm'中的未知寄存器名称'%es'”(这是唯一的错误消息)。 我最好的猜测是它在GAS语法中有另一个名字。 我知道我正在使用旧的代码,但据我所知,在我相当新的intel i3上仍然有一个ES寄存器被stos使用*

    其次,有一个问题困扰着我。 我基本上别无选择,只能假设DS已经设置到正确的内存位置以便与lods *一起使用。 因为我正在读取,修改和写入相同的内存位置(使用stos *和lods *),所以我将ES设置为DS。 但是,真的让我感到害怕,我的DS可能是任何东西,我不知道还有什么可以设置的。 更重要的是,ESI和EDI已经是32位寄存器,并且应该足以自己访问内存。

    根据我的经验,两个奇怪的问题一次通常是由一个更基本的问题(通常是PEBKAC)引起的。 不过,我很困惑这一点。 有谁知道发生了什么事?

    谢谢一堆

    PS我试图重新创建第9章(提示我的读者给我,清单9.5,第182页)中的代码,它将存储在EBX中的大量连续内存中。 除了我个人的成长和娱乐之外,没有其他理由这样做。


    如果您运行的是32位平面保护模式环境(如Linux或Windows用户模式进程),则无需设置es。

    段寄存器由OS为您设置,并且es和ds都允许您访问一个扁平的32位地址空间。

    GCC不会生成保存/恢复段寄存器的代码,所以不会让您将它们添加到clobber列表中并不奇怪。

    链接地址: http://www.djcxy.com/p/59753.html

    上一篇: Can't seem to add %ES to the clobberlist (inline assembly, GCC)

    下一篇: Assembly generated from NEON intrinsics [LLVM