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

时间:2014-07-04 17:20:18

标签: c gcc assembly inline-assembly

我正在阅读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是返回值(an unsigned int)函数并在程序集块内部设置 是该师的其余部分。

我得到的错误消息是“错误:'asm'中的未知寄存器名'%es'”(这是唯一的错误消息)。我最好的猜测是它在GAS语法中有另一个名字。我知道我正在使用旧代码,但据我所知,在我相当新的intel i3上仍有一个ES寄存器被stos使用*

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

根据我的经验,两个奇怪的问题通常是相关的,并且由更基本的问题(通常是PEBKAC)引起。但是,我在这一点上很难过。有谁知道发生了什么事?

非常感谢

P.S。我正在尝试重新创建第9章(Hints My Readers Gave Me,清单9.5,第182页)中的代码,该代码通过EBX划分存储在连续内存中的大量数字。没有其他原因可以做到这一点,而不是我个人的成长和娱乐。

1 个答案:

答案 0 :(得分:5)

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

段寄存器由OS设置,es和ds都允许您访问平坦的32位地址空间。

GCC不会生成保存/恢复段寄存器的代码,因此它不允许您将它们添加到clobber列表中也就不足为奇了。