1

I'm trying to understand how to encode reads on the RSP register in x86-64.

For example, I have some code like this:

.section __TEXT,__text
.global _main

_main:
  push %rsp
  push (%rsp)
  mov %rsp, %rax
  mov (%rsp), %rax

When I assemble and dump the output, it looks like this:

$ as -o thing.o thing.s && objdump -d thing.o
                                                      
thing.o:        file format mach-o 64-bit x86-64      
                                                      
                                                      
Disassembly of section __TEXT,__text:                 
                                                      
0000000000000000 <add2>:                              
       0: 54                            pushq   %rsp  
       1: ff 34 24                      pushq   (%rsp)
       4: 48 89 e0                      movq    %rsp, %rax
       7: 48 8b 04 24                   movq    (%rsp), %rax

push (%rsp) becomes ff 34 24. From what I understand, 0xFF is the opcode for PUSH, and 0x34 is Mod/RM encoding. I don't understand where 0x24 is coming from though. Is this the SIB byte? How is this instruction encoded? I can't seem to follow the Intel manual well enough to figure out where this byte comes from. I see the same byte in mov (%rsp), %rax.

4

1 回答 1

2

To encode push (%rsp) look up the push instruction in the instruction set reference. You will see it is listed as FF /6. Then turn to chapter 3.1 INTERPRETING THE INSTRUCTION REFERENCE PAGES, in particular, section 3.1.1.1 Opcode Column in the Instruction Summary Table where you will see:

/digit A digit between 0 and 7 indicates that the ModR/M byte of the instruction uses only the r/m (register or memory) operand. The reg field contains the digit that provides an extension to the instruction's opcode.

To encode (%rsp) (or [rsp] in intel syntax) you will need a SIB byte. Consult Table 2-2. 32-Bit Addressing Forms with the ModR/M Byte. While it says 32 bit, it mostly applies to 64 bit as well with the logical extensions. Since the instruction has /6 look at the penultimate column, and the row that says [--][--] with the footnote telling you this is the one that allows you to specify a SIB byte. The value in this cell is 34 (hex) so that's where that comes from. As for the SIB byte itself, consult the next Table 2-3. 32-Bit Addressing Forms with the SIB Byte. You want the column with the heading ESP (the 32 bit equivalent to RSP) and the row none which gives you the 24.

于 2021-09-15T22:07:40.170 回答