什么是寄存器 %eiz?

Posted

技术标签:

【中文标题】什么是寄存器 %eiz?【英文标题】:What is register %eiz? 【发布时间】:2011-02-02 22:55:45 【问题描述】:

在我使用objdump 转储的以下汇编代码中:

lea    0x0(%esi,%eiz,1),%esi

什么是寄存器%eiz?上面的代码是什么意思?

【问题讨论】:

你可能会觉得sourceware.org/ml/binutils/2009-01/msg00081.html很有趣。 【参考方案1】:

见Why Does GCC LEA EIZ?:

显然%eiz 是一个伪寄存器,它始终只计算为零(就像 MIPS 上的 r0)。

...

我最终找到了 binutils 大师 Ian Lance Taylor 的邮件列表帖子,其中揭示了答案。有时 GCC 会在代码流中插入 NOP 指令以确保正确对齐和类似的东西。 NOP 指令占用一个字节,因此您会认为可以根据需要添加任意数量的字节。但根据 Ian Lance Taylor 的说法,芯片执行一条长指令比执行许多短指令要快。因此,它们没有插入 7 个 NOP 指令,而是使用了一个 bizarro LEA,它占用了 7 个字节并且在语义上等同于 NOP。

【讨论】:

聪明人 :) 感谢您的回答!因此上面的代码只是 nop 的更长版本:P 更具体地说,它是一个不必要的 SIB 字节的占位符,它编码没有索引的寻址模式。【参考方案2】:

Andy Ross 提供了更多基本推理,但不幸的是,他错了,或者至少对技术细节感到困惑。确实,仅(%esp) 的有效地址不能仅使用 ModR/M 字节进行编码,因为它不会被解码为 (%esp),它用于表示还包括 SIB 字节。但是,%eiz 伪寄存器并不总是与 SIB 字节一起使用来表示使用了 SIB 字节。

SIB 字节(标度/索引/基址)包含三个部分:索引(应用标度的寄存器,例如 %eax%ecx),标度(从索引寄存器乘以 1 到 8)和基数(添加到缩放索引的另一个寄存器)。这就是允许诸如 add %al,(%ebx,%ecx,2) 之类的指令(机器代码:00 04 4b -- opcode, modr/m, sib(注意没有 %eiz 寄存器,即使使用了 SIB 字节))(或者在 Intel 语法中,“添加BYTE PTR [ecx*2+ebx], al")。

但是,%esp 不能用作 SIB 字节中的索引寄存器。英特尔没有允许此选项,而是添加了一个选项,可以按原样使用基址寄存器,而无需缩放或索引。因此,为了区分add %al,(%ecx)(机器代码:00 01 -- opcode,modr/m)和add %al,(%ecx)(机器代码:00 04 21 -- opcode,modr/m,sib)的情况,替代语法改为使用 add %al,(%ecx,%eiz,1)(或 Intel 语法:add BYTE PTR [ecx+eiz*1],al)。

正如思南链接的文章中所解释的,这条特定指令(lea 0x0(%esi,%eiz,1),%esi)仅用作多字节 nop(相当于esi = &*esi),因此只需执行一条类似 nop 的指令而不是多个 nop 指令。

【讨论】:

顺便说一句,ESP 不能成为索引的原因是(%esp) 是一种比(%esp, %esp, 1..8) 更有用的寻址模式。由于您无法在没有 SIB 字节的情况下对 base=ESP 进行编码,因此您需要某种方式来指定无索引。 (因为没有基地需要 disp32,而且他们不想要求 disp32=0( , %esp, 1) 使 ESP 相对寻址变得不合理地昂贵。)【参考方案3】:

(游戏很晚,但这似乎是一个有趣的补充):它根本不是一个寄存器,它是 Intel 指令编码的一个怪癖。当使用 ModRM 字节从内存中加载时,寄存器字段有 3 位用于存储 8 个可能的寄存器。但是,ESP(堆栈指针)“将”所在的位置被处理器解释为“SIB 字节遵循该指令”(即,它是扩展寻址模式,而不是对 ESP 的引用)。由于只有作者知道的原因,GNU 汇编器总是将这个“寄存器本来应该是零”表示为“%eiz”寄存器。英特尔语法只是删除它。

【讨论】:

binutils 仅对 redundant SIB 字节执行此操作(即 E/RSP 以外的基本字节,并且没有索引)。它使用(%esp) / (%rsp) 而不是(%esp, %eiz, 1) 这是适合 GNU 汇编器的输入,还是只是反汇编器的功能? 上述原因可能是IZ代表索引零。

以上是关于什么是寄存器 %eiz?的主要内容,如果未能解决你的问题,请参考以下文章

寄存器是什么?内存寄存器和存储器的区别

什么是STM32的高寄存器和低寄存器?

寄存器由啥芯片组成

什么决定CPU寄存器和总线的数据宽度

寄存器是啥 有啥作用

ESP寄存器和SS寄存器有什么区别?