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
.
CodePudding user response:
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
.