To make a normal (near direct relative) call
to an absolute address, in NASM or AT&T syntax you write call 0x1234567
, and the assembler + linker take care of calculating a rel32
to reach that target from wherever the linker puts the call
instruction.
e.g. on Linux assembling that into a static 64-bit ELF executable with yasm -felf64 foo.asm && ld foo.o -o foo
, then disassembled with objdump -drwC -Mintel foo
gives you:
foo: file format elf64-x86-64
Disassembly of section .text:
0000000000400080 <_start>:
400080: e8 e2 44 e3 00 call 1234567 <_end+0xc344df>
The linker calculated the right rel32 to reach 0x1234567
from 0x400080+5
, based on a R_X86_64_PC32
relocation in the object file:
0: e8 00 00 00 00 call 5 <_start+0x5> 1: R_X86_64_PC32 *ABS*+0x1234563
How do you get MASM and/or MSVC inline-asm to do that?
MSVC doesn't accept _asm { call 1234567h; }
. The error is C2415: improper operand type
. The only SO answer I've found suggests using a workaround of an indirect jmp with the address in memory or a register, but making inefficient machine code because of hard-to-use tools isn't a very good solution.
I don't have MASM at all, so I've only been able to try MSVC inline-asm (which is not the same thing) on the Godbolt compiler explorer.
Can you set the address of a label and use it as a target for call symbol
? Like with GAS's .set symbol, 0x1234567
which lets you give a symbol an address without having to actually writing symbol:
anywhere.
Can you emit the encoding directly with db 0E8h
/ dd 1234567h - ($ + 4)
? Probably not, in NASM that only works with label - $
, not absolute - label
I'm mostly interested in the answer so I can include it in my canonical answer about jmp/call to an absolute address: Call an absolute pointer in x86 machine code Definitely not for any code I want to actually use.
See Question&Answers more detail:
os 与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…