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

Mah*_*koe 2 c assembly gcc 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"
);
Run Code Online (Sandbox Code Playgroud)
  • l变量是一个无符号int,则p变量是一个char*.l 是指向的字符串长度的字节数p.div 是除数,是一个无符号整数.ret是函数的返回值(无符号整数),并在程序段内部设置为除法的余数.

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

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

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

谢谢一堆

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

Jon*_*art 5

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

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

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