Чтобы сделать нормальное (почти прямое относительное) call
к абсолютному адресу, в синтаксисе NASM или AT & T вы пишете call 0x1234567
, а ассемблер + компоновщик позаботится о вычислении rel32
для достижения этой цели отовсюду компоновщик помещает инструкцию call
.
например. сборка в Linux в статический 64-битный исполняемый файл ELF с yasm -felf64 foo.asm && ld foo.o -o foo
, затем дизассемблирование с objdump -drwC -Mintel foo
дает:
foo: file format elf64-x86-64
Disassembly of section .text:
0000000000400080 <_start>:
400080: e8 e2 44 e3 00 call 1234567 <_end+0xc344df>
Компоновщик вычислил правильное значение rel32 для достижения 0x1234567
из 0x400080+5
, основываясь на перемещении R_X86_64_PC32
в объектном файле:
0: e8 00 00 00 00 call 5 <_start+0x5> 1: R_X86_64_PC32 *ABS*+0x1234563
Как вы получаете MASM и / или MSVC inline-asm для этого?
MSVC не принимает _asm { call 1234567h; }
. Ошибка C2415: improper operand type
. Единственный найденный мной SO-ответ предлагает использовать обходной путь косвенного jmp с адресом в памяти или регистре, но создание неэффективного машинного кода из-за сложных в использовании инструментов не очень хорошо решение.
У меня вообще нет MASM, поэтому я только смог попробовать inline-asm MSVC (что не одно и то же) в проводнике компилятора Godbolt .
Можете ли вы установить адрес метки и использовать его в качестве цели для call symbol
? Как и в случае с .set symbol, 0x1234567
GAS, который позволяет дать символу адрес без необходимости писать symbol:
в любом месте.
Можете ли вы передать кодировку напрямую с помощью db 0E8h
/ dd 1234567h - ($ + 4)
? Вероятно, нет, в NASM, который работает только с label - $
, а не absolute - label
Меня больше всего интересует ответ, поэтому я могу включить его в свой канонический ответ о jmp / call на абсолютный адрес: Вызвать абсолютный указатель в машинном коде x86 Определенно не для любого кода, который я хочу на самом деле использовать.