什么是注册%eiz?

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

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

什么是注册%eiz ? 前面的代码是什么意思?

3 Solutions collect form web for “什么是注册%eiz?”

看看为什么GCC LEA EIZ? :

显然%eiz是一个伪寄存器,只是在任何时候都评估为零(就像MIPS上的r0 )。

我最终通过binutils guru Ian Lance Taylor发现了一个邮件列表post,揭示了答案。 有时GCC会在代码stream中插入NOP指令,以确保正确的alignment和类似的东西。 NOP指令需要一个字节,所以你会认为你可以根据需要添加多less个字节。 但根据Ian Lance Taylor的说法,芯片执行一条长指令比多条短指令要快。 因此,而不是插入七个NOP指令,而是使用一个bizarro LEA,它使用了七个字节,在语义上等同于一个NOP。

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

安迪·罗斯提供了更多的深层推理,但不幸的是,这个技术细节是错误的,或者至less是令人困惑的。 确实,只有(%esp)的有效地址不能用ModR / M字节进行编码,而是被解码为(%esp) ,这是用来表示SIB字节也包含在内的。 但是, %eiz伪寄存器并不总是与SIB字节一起使用来表示使用了SIB字节。

SIB字节(比例/索引/基数)有三个部分:索引(一个寄存器,例如%eax%ecx ,即比例应用于),比例(从1到8的两个幂索引寄存器乘以)和基址(另一个被添加到缩放索引的寄存器)。 这是允许的指令,如add %al,(%ebx,%ecx,2) (机器码: 00 04 4b – 操作码,modr / m,sib(注意即使使用SIB字节,也不注意%eiz寄存器) ))(或在Intel语法中,“add 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 )。

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

  • 在x86上将float转换为int的最快方法是什么?
  • 如何为android-ndk8b(x86 arch Android)构buildi686-linux-android-gfortran?
  • 在C ++内联asm中使用基指针寄存器
  • 为什么GCC在分配variables之前将variables移动到临时位置?
  • 如何使用gcc生成英特尔语法的汇编代码?
  • 为什么这样复杂的代码是用二的幂来分割一个有符号的整数?
  • 你如何组装一个汇编程序?
  • 如何反汇编原始x86代码?
  • 如何确定.NET程序集是为x86还是x64构建的?
  • 帮我理解这个JavaScript漏洞
  • 为什么gcc允许从结构中投机加载?