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

Posted

技术标签:

【中文标题】似乎无法将 %ES 添加到clobberlist(内联汇编,GCC)【英文标题】:Can't seem to add %ES to the clobberlist (inline assembly, GCC) 【发布时间】:2014-07-04 17:20:18 【问题描述】:

我正在阅读 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 变量是无符号整数,p 变量是 char*。 lp 指向的字符串长度的字节数。 div 是除数,是一个无符号整数。 ret 是返回值(一个 unsigned int) 并设置在汇编块内部 是除法的余数。

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

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

根据我的经验,两个奇怪的问题通常是相关的,并且是由一个更基本的问题(通常是 PEBKAC)引起的。然而,我在这一点上被难住了。有谁知道怎么回事?

非常感谢

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

【问题讨论】:

【参考方案1】:

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

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

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

【讨论】:

谢谢,这正是我想要的。

以上是关于似乎无法将 %ES 添加到clobberlist(内联汇编,GCC)的主要内容,如果未能解决你的问题,请参考以下文章

无法将组件添加到扩展 JFrame 的类

递归Java后无法将文件添加到列表

为啥 ES5 Object 方法没有添加到 Object.prototype 中?

OpenGL ES 2.0:似乎无法渲染第二个 VBO?

无法将项目添加到 UIToolbar

无法将标签栏应用程序添加到 popToRootViewController