What is the% eiz register?

In the following assembler, which I dumped with objdump :

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

What is the %eiz ? What does the previous code mean?

+48
assembly x86 gas objdump
Mar 31 '10 at 13:57
source share
3 answers

See Why GCC LEA EIZ? :

%eiz be a pseudo- %eiz that simply evaluates to zero at any time (e.g. r0 on MIPS).

...

I eventually found the binutils guuru Ian Lance Taylor mailing list that reveals the answer. Sometimes GCC inserts NOP instructions into the code stream to ensure proper alignment and the like. The NOP instruction takes one byte, so you might think that you can just add as many as needed. But, according to Ian Lance Taylor, it is faster for a chip to execute one long instruction than many short instructions. Therefore, instead of inserting seven NOP instructions, instead they use one bizarro LEA, which uses seven bytes and is semantically equivalent to NOP.

+50
Mar 31 '10 at 14:03
source share

(Very late in the game, but it seemed like an interesting addition): This is not a registration at all, this is a fad of encoding Intel instructions. When using the ModRM byte for loading from memory, 3 bits are used in the register field to store 8 possible registers. But the place where the ESP (stack pointer) "will be" is instead interpreted by the processor, since the "SIB byte follows this instruction" (ie This is an extended addressing mode, not a reference to ESP). For reasons known only to the authors, the GNU assembler has always represented this "zero, where case would otherwise be" like case "% eiz". Intel's syntax just drops it.

+20
Aug 28 2018-12-12T00:
source share

Andy Ross provides much more fundamental arguments, but unfortunately is mistaken or at least confuses the technical details. It is true that the effective address only (%esp) cannot be encoded with the ModR / M byte only, and instead of being decoded as (%esp) , it is used to signal the inclusion of the SIB byte. However, the %eiz pseudo- %eiz not always used with the SIB byte to represent that the SIB byte was used.

The SIB byte (scale / index / base) has three elements: the index (register, for example %eax or %ecx to which the scale applies), scale (the power of two from 1-8, that the index register is multiplied by), and the base (another register that is added to the scaled index). This is what allows the use of commands such as add %al,(%ebx,%ecx,2) (machine code: 00 04 4b - operation code, modr / m, sib (pay attention to the% eiz case, even if used SIB byte)) (or in Intel syntax, "add BYTE PTR [ecx * 2 + ebx], al").

However, %esp cannot be used as an index register in the SIB byte. Instead of allowing this option, Intel instead adds the ability to use a base register that does not have scaling or indexing. Therefore, to eliminate the ambiguity between the case add %al,(%ecx) (machine code: 00 01 is the operation code, modr / m) and add %al,(%ecx) (machine code: 00 04 21 is the operation code, modr / m, sib), alternative syntax add %al,(%ecx,%eiz,1) (or for Intel syntax: add BYTE PTR [ecx+eiz*1],al ).

And as explained in the Sinan related article, this particular instruction ( lea 0x0(%esi,%eiz,1),%esi ) is just used as a multibyte nop (equivalent to esi = &*esi ), so only one nop should be executed -like instruction instead of several nop instructions.

+12
Jan 15
source share



All Articles