Сборка x86 16-битный относительный вызов - PullRequest
0 голосов
/ 18 октября 2018

Я заметил, что в x86 доступны следующие две инструкции по сборке:

E8 cw    CALL rel16
E8 cd    CALL rel32

Я запутался, как процессор инструкций может различать эти два вызова.Единственное, о чем я могу думать, это то, что если приложение является 16-разрядным, IP предполагает наличие первого, а если приложение является 32-разрядным, то IP принимает второе.Верна ли моя интерпретация, или есть способ кодировать CALL rel16 в 32-битное приложение?

1 Ответ

0 голосов
/ 25 октября 2018

Этот ответ был предоставлен Michael Petch в комментариях к вопросу:

Размер операнда (который определяет, является ли он rel16 или rel32) имеет другой размер по умолчаниюв зависимости от режима процессора (реальный режим / 32-битный защищенный режим / 16-битный защищенный режим / 64-битный длинный режим / режим V8086 и т. д.).Вы можете увидеть этот график для деталей .Вы можете переопределить значение по умолчанию с префиксом операнда 0x66.В 32-разрядном режиме вы можете использовать префикс инструкции 0x66, чтобы изменить значение по умолчанию с 32-разрядного размера операнда на 16-разрядный.

Я заметил, что 16-разрядные старшие разряды EIP обнуляются, когдаиспользуя эту инструкцию.Следовательно, 0x66 0xE8 16-битный относительный вызов имеет следующую семантику C ++:

int16_t offset = ...;
EIP = (EIP + offset) & 0xFFFF;

Так что да, в 32-битном приложении можно использовать 16-битную инструкцию относительного вызова.

...