генерация операнда инструкции CALL на x86-64 AMD - PullRequest
6 голосов
/ 25 февраля 2012

Ниже приведен вывод objdump примера программы,

080483b4 <display>:
 80483b4:       55                      push   %ebp
 80483b5:       89 e5                   mov    %esp,%ebp
 80483b7:       83 ec 18                sub    $0x18,%esp
 80483ba:       8b 45 0c                mov    0xc(%ebp),%eax
 80483bd:       89 44 24 04             mov    %eax,0x4(%esp)
 80483c1:       8d 45 fe                lea    0xfffffffe(%ebp),%eax
 80483c4:       89 04 24                mov    %eax,(%esp)
 80483c7:       e8 ec fe ff ff          call   80482b8 <strcpy@plt>
 80483cc:       8b 45 08                mov    0x8(%ebp),%eax
 80483cf:       89 44 24 04             mov    %eax,0x4(%esp)
 80483d3:       c7 04 24 f0 84 04 08    movl   $0x80484f0,(%esp)
 80483da:       e8 e9 fe ff ff          call   80482c8 <printf@plt>
 80483df:       c9                      leave
 80483e0:       c3                      ret

080483e1 <main>:
 80483e1:       8d 4c 24 04             lea    0x4(%esp),%ecx
 80483e5:       83 e4 f0                and    $0xfffffff0,%esp
 80483e8:       ff 71 fc                pushl  0xfffffffc(%ecx)
 80483eb:       55                      push   %ebp
 80483ec:       89 e5                   mov    %esp,%ebp
 80483ee:       51                      push   %ecx
 80483ef:       83 ec 24                sub    $0x24,%esp
 80483f2:       c7 44 24 04 f3 84 04    movl   $0x80484f3,0x4(%esp)
 80483f9:       08
 80483fa:       c7 04 24 0a 00 00 00    movl   $0xa,(%esp)
 8048401:       e8 ae ff ff ff          call   80483b4 <display>
 8048406:       b8 00 00 00 00          mov    $0x0,%eax
 804840b:       83 c4 24                add    $0x24,%esp
 804840e:       59                      pop    %ecx
 804840f:       5d                      pop    %ebp
 8048410:       8d 61 fc                lea    0xfffffffc(%ecx),%esp

То, что мне нужно понять, в основном мы видим по адресу 8048401, звоните 80483b4, однако машинный код - e8 ae ff ff ff Я вижу, что инструкция CALL - это E8, но как адрес функции 80483b4 декодируется в FFFFFFAE? Я сделал много поиска в Google, но он ничего не возвращал. Кто-нибудь может объяснить, пожалуйста?

Ответы [ 3 ]

10 голосов
/ 25 февраля 2012

E8 - операнд для «Относительного вызова», то есть адрес получателя вычисляется путем добавления операнда к адресу следующей инструкции. Операндом является 0xFFFFFFAE, который является отрицательным 0x52. 0x808406 - 0x52 - это 0x80483b4.

Большинство дизассемблеров помогает вычислить фактический целевой адрес, а не просто дает вам относительный адрес в операнде.

Полная информация для x86 ISA по адресу: http://www.intel.com/content/www/us/en/architecture-and-technology/64-ia-32-architectures-software-developer-vol-2a-manual.html

6 голосов
/ 25 февраля 2012

Интересный вопрос.Я посмотрел на документацию Intel , а код операции E8 - CALL rel16/32.0xffffffae на самом деле представляет собой 32-разрядное целое число со знаком со знаком два, равное -82 десятичному числу;это относительный адрес из байта сразу после кода операции и его операндов.

Если вы выполните математику, вы увидите, что она проверяется:

0x8048406 - 82 = 0x80483b4

Это помещает указатель инструкции в начало функции display.

3 голосов
/ 25 февраля 2012

Ближайшие вызовы, как правило, относятся к IP - это означает, что «адрес» фактически является смещением от указателя инструкции. В этом случае EIP указывает на следующую инструкцию (поэтому ее значение равно 8048406). Добавьте к нему ffffffae (или -00000052 в двух дополнениях), и вы получите 80483b4.

Обратите внимание, что вся эта математика является 32-битной. Вы не выполняете здесь никаких 64-битных операций (или ваши регистры будут иметь R с вместо E с в их именах, и адреса будут намного длиннее).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...