Как написать абсолютную цель для почти прямого относительного вызова / JMP в MASM - PullRequest
0 голосов
/ 27 апреля 2018

Чтобы сделать нормальное (почти прямое относительное) 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 Определенно не для любого кода, который я хочу на самом деле использовать.

1 Ответ

0 голосов
/ 24 ноября 2018

MASM не поддерживает это, потому что формат объектного файла COFF не поддерживает необходимое перемещение. (Или правильно не поддерживает это? Согласно сообщению об ошибке NASM.)

Использование синтаксиса call 0x76cd75c0 в nasm -f win32 приводит к ошибке:

error: Win32 COFF does not correctly support relative references to absolute addresses

Я не знаю, может ли MASM ориентироваться на плоские двоичные файлы реального режима (где нет объектных файлов, которые должны описывать перемещения к компоновщику), но, вероятно, MASM просто был разработан без синтаксиса для него вообще, к сожалению, .


См. Также Ошибка при непосредственном вызове функции в user32.dll . Я сам попробовал nasm -fwin32 2.13.02 на рабочем столе Linux и получил ту же ошибку.


Непроверенный возможный обходной путь может заключаться в создании .obj с определением символа для этого абсолютного адреса, например

org 0deadbeefH
global my_target
my_target:

в NASM или как вы это делаете в MASM.

Тогда в MASM или MSVC inline-asm вы можете использовать jmp my_target и связать с этим .obj. Теоретически это может обойти проблему представления перемещений в объектном файле и заставить компоновщик рассчитать относительное смещение ветвей.

...