在下面的组件的代码,我倒出使用objdump

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

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

有帮助吗?

解决方案

请参阅为什么GCC LEA EIZ

  

显然%eiz是在所有时间的伪寄存器,仅仅计算结果为零(如r0在MIPS)。

...

  

我最终发现的binutils大师伊恩·兰斯·泰勒邮件列表后,揭示了答案。有时候GCC插入NOP指令到代码流,以确保正确对齐和类似的东西。 NOP指令需要一个字节,所以你会觉得需要你可以只添加尽可能多的。但根据伊恩·兰斯·泰勒,这对芯片的速度比许多短指令来执行一个长指令。因此,而不是插入7 NOP指令,它们代替使用一个比扎罗LEA,它采用了7个字节和在语义上等同于一个NOP。

其他提示

(很晚了比赛,但是这似乎是一个有趣的加法):这不是在所有的寄存器,它是英特尔指令编码的怪癖。当使用ModRM字节从存储器加载,有用于寄存器字段来存储8个可能的寄存器3个比特。但是,在ESP(堆栈指针)“将”被改为由处理器解释为点“一个SIB字节跟随这个指令”(即它是一个扩展寻址模式,而不是到ESP的引用)。对于只知道作者的原因,GNU汇编始终代表着这个“零其中一个寄存器否则将”为“%eiz”注册。英特尔语法只是丢弃。

安迪·罗斯提供底层推理多了很多,但不幸的是错误的或者至少是混淆有关的技术细节。这是事实,只是(%esp)的有效地址不能只用MODR / M字节作为代替被解码为(%esp)被编码,它用于信号,还安装有一个SIB字节。然而,%eiz伪寄存器不总是与SIB字节用于表示使用了SIB字节。

在SIB字节(比例/索引/碱)具有三块它:索引(一个寄存器如作为%eax%ecx该量表被施加到),规模(二的幂从1到8,其索引寄存器乘以)和所述基部(被添加到经缩放的索引的另一寄存器)。这是允许诸如add %al,(%ebx,%ecx,2)(机器码:00 04 4b - 操作码,MODR / M,SIB(注意没有%eiz即使使用了SIB字节寄存器))的指令(或Intel语法“中,添加BYTE PTR [ECX * 2 + EBX],人“)。

然而,%esp不能用作在SIB字节的索引寄存器。相反,允许这种选择的,而不是英特尔增加了使用的基址寄存器作为与不结垢或索引选项。和add %al,(%ecx)(机器代码:00 01 - 操作码,MODR /米,SIB) - :因此,为了add %al,(%ecx)的情况下(操作码,MODR /米00 04 21机器代码)之间消除歧义,替代语法add %al,(%ecx,%eiz,1)是使用(或用于英特尔语法:add BYTE PTR [ecx+eiz*1],al

和由思南链接到在文章中所解释的,这个特定的指令(lea 0x0(%esi,%eiz,1),%esi)仅用作一个多字节NOP(相当于esi = &*esi),以便只有一个NOP状指令已被执行而不是多个NOP指令。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top