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.

Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
Aaron Patterson
  • 2,275
  • 1
  • 20
  • 11
  • https://stackoverflow.com/questions/29600668/what-meaning-if-any-does-the-mod-r-m-byte-carry-for-the-unconditional-jump-ins – Hans Passant Sep 15 '21 at 21:47

1 Answers1

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.

Jester
  • 56,577
  • 4
  • 81
  • 125