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