This question is not about LEA instruction, not about how it works at all, it is not a duplicate. This is about OPCODE generation for this instruction.
What is the operand number in LEA opcode?
Here is my "hello world.fasm":
Assembler program:
format ELF64 executable at 0000000100000000h ; put image over 32-bit limit
segment readable executable
entry $
mov edx,msg_size ; CPU zero extends 32-bit operation to 64-bit
; we can use less bytes than in case mov rdx,...
lea rsi,[msg]
mov edi,1 ; STDOUT
mov eax,1 ; sys_write
syscall
xor edi,edi ; exit code 0
mov eax,60 ; sys_exit
syscall
segment readable writeable
msg db 'Hello 64-bit world!',0xA
msg_size = $-msg
Hex dump:
000000b0 ba 14 00 00 00 48 8d 35 15 10 00 00 bf 01 00 00 |.....H.5........|
000000c0 00 b8 01 00 00 00 0f 05 31 ff b8 3c 00 00 00 0f |........1..<....|
000000d0 05 48 65 6c 6c 6f 20 36 34 2d 62 69 74 20 77 6f |.Hello 64-bit wo|
000000e0 72 6c 64 21 0a |rld!.|
000000e5
As you can see, the instruction of interest lea rsi, [msg]
has the opcodes: 48 8d 35 15 10 00 00
. From the CPU instruction reference I can tell that 48
is the 64 bit prefix of sort, 8d
is the LEA
code, 35
is destination register rsi
reference, and 15 10 00 00
is...??? What is it?
0x15
is 21
in decimal, and I can count with a finger tracking the hex dump that "Hello world" message is exactly 21 bytes after the LEA rsi, [msg]
instruction. So it must be a relative address, but where 10 00 00
comes from? I would understand if it was 15
00 00 00
, but for some reason it is 15
01 00 00
.
Unfortunately CPU references are not very helpful, they are so formal and I cannot get on terms with them. They look like this:
8D r LEA Gvqp M gen datamov Load Effective Address
So please explain how the LEA
opcode is generated in this case, and if possible in general.