1
votes

I disassemble ( with objdump -d ) this opcode (c7 45 fc 05 00 00 00) and get this (mov DWORD PTR [rbp-0x4],0x5). then i try to decode myself and i think it should be (mov DWORD PTR [ebp-0x4],0x5) . Why it is RBP register but not EBP register ? am i missing something ?

Here what i have try: First i look at the mov opcode for C7 opcode.

C7 /0 iw | MOV r/m16,imm16

C7 /0 id | MOV r/m32,imm32

REX.W + C7 /0 id | MOV r/m64,imm32

so there is no REX.W prefix here, and there also no +rb,+rw,+rd,+ro here. /0 mean ModR/M byte only use r/m register, reg/opcode field can safely ignore here. so 0x45 translate to [EBP]+disp8 (using table2-2. 32-bit addressing forms with the modR/M byte in Volume 2/chapter 2 ). disp8 is 0xfc -> -4. and the rest of the opcode is (05 00 00 00) is imm32.

1

1 Answers

2
votes

In 64 bit mode, the default address size is 64 bit: without the address size override prefix (that's 67h, not REX.W) the 64 bit variants of registers will be used in address calculation. That's nice, you almost always want a 64 bit address calculation in 64 bit mode, if that was not the default then there would be a lot of wasted prefixes. The REX.W prefix does not affect address size but "operation size", REX.W + C7 ... is the encoding for mov QWORD PTR [...], imm32.

So, when assembling for 64 bit mode, mov DWORD PTR [ebp-0x4],0x5 would be encoded as 67 c7 45 fc 05 00 00 00, and when disassembling c7 45 fc 05 00 00 00 for 64 bit mode it means mov DWORD PTR [RBP-0x4],0x5.

An interesting consequence of these defaults is that the shortest forms of lea use a 64 bit address but a 32 bit destination, which looks a bit wrong at first.