assembly - Why does `call dword 0x12345678` compile to [66,E8,72,56,34,12]? -
$ cat call.s call dword 0x12345678 $ nasm call.s $ ndisasm call 00000000 66e872563412 call dword 0x12345678
why result [66,e8,72,56,34,12] not [66,e8,78,56,34,12]? why did 0x78
change 0x72
?
you are calling absolute address instruction, although may not seem obvious @ first glance. let's go through assembly process step step.
firstly, can see instruction has been assembled 66 e8
. 66
operand size prefix - i'll explain why got there later. e8
points call
instruction, expected, , following bytes - 72563412
- little-endian representation of 32-bit displacement relative instruction after call
instruction. how relative jumps , calls encoded in x86 : because cpu knows current value of instruction pointer, can add value specified instruction value , execute call/jump.
secondly, there question why assembler chose assemble instruction way. if running nasm
without flags, defaults bin
output mode, outputs raw opcodes file specify. additionally, defaults assembling instructions in 16-bit mode in output mode. why 66
prefix there : possible execute instructions 32-bit operands in 16-bit mode, provided prefix present in front of opcode. also, nasm
in bin
output mode assumes resulting binary begins @ address 0
: why "offset" of call 72563412
- if ip starts @ 0, 6 after processing call
, , 0x6 + 0x12345672
gives 0x12345678
, address wanted call. can change offset @ program loaded via org
(origin) directive.
if don't want use jumps/calls relative addressing, have put address of code want jump to/call in register, , execute instruction register operand. :
mov eax, somecode jmp eax somecode: int 3
assembles following :
00000000 66b809000000 mov eax,0x9 00000006 66ffe0 jmp eax 00000009 cd03 int 0x3
you can see absolute address of jump moved directly register. however, if you're executing jumps/calls labels, can't think of reasons why wouldn't use relative addressing. cpu knows current ip - , assembler should, too.
Comments
Post a Comment