изучение разборки - PullRequest
4 голосов
/ 10 января 2011

В попытке понять, что происходит ниже, я делаю небольшие программы на C, а затем обращаюсь к нему и пытаюсь понять его вывод objdump.

Программа на C:

#include <stdio.h>

int function(int a, int b, int c) {
    printf("%d, %d, %d\n", a,b,c);
}

int main() {
    int a;
    int *ptr;

    asm("nop");
    function(1,2,3);
}

Вывод objdump для функции дает мне следующее.

080483a4 <function>:
 80483a4:   55                      push   ebp
 80483a5:   89 e5                   mov    ebp,esp
 80483a7:   83 ec 08                sub    esp,0x8
 80483aa:   ff 75 10                push   DWORD PTR [ebp+16]
 80483ad:   ff 75 0c                push   DWORD PTR [ebp+12]
 80483b0:   ff 75 08                push   DWORD PTR [ebp+8]
 80483b3:   68 04 85 04 08          push   0x8048504
 80483b8:   e8 fb fe ff ff          call   80482b8 <printf@plt>
 80483bd:   83 c4 10                add    esp,0x10
 80483c0:   c9                      leave  

Обратите внимание, что перед вызовом printf три DWORD со смещениями 8,16,12 (они должны быть аргументами function в обратном порядке) помещаются в стек. Позже вводится шестнадцатеричный адрес, который должен быть адресом строки формата.

My doubt is

  1. Вместо того, чтобы помещать 3 DWORDS и спецификатор формата непосредственно в стек, я ожидал увидеть, что esp будет вручную уменьшен, а после этого значения будут помещены в стек. Как можно объяснить это поведение?

Ответы [ 6 ]

5 голосов
/ 10 января 2011

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

Но некоторые машины, такие как x86 32/64 имеет команду push , которая выполняет макрооперацию: уменьшение указателя и в хранилище.

Макрооперации,Кстати, есть забавная история.Иногда некоторые примеры на некоторых машинах выполняются медленнее, чем выполнение элементарных операций с простыми инструкциями.

Я сомневаюсь, что это часто случается сегодня.Современный x86 удивительно сложен.Процессор будет самостоятельно разбирать ваши коды операций на микрооперации, которые затем будет храниться в кэше.Микрооперации предъявляют особые требования к конвейеру и временным интервалам, и в результате в эти дни в x86 есть процессор RISC, и все идет очень быстро , а имеет хорошую плотность кода архитектурного уровня.

1 голос
/ 10 января 2011

Это стандартное соглашение о вызовах cdecl для машины x86.Существует несколько различных типов соглашений о вызовах.Вы можете прочитать следующую статью в Википедии об этом:

http://en.wikipedia.org/wiki/X86_calling_conventions

Это объясняет основной принцип.

1 голос
/ 10 января 2011

Нет инструкции mov [esp + x], [ebp + y], слишком много операндов. Это займет две инструкции и использовать регистр. Push делает это в одной инструкции.

1 голос
/ 10 января 2011

Указатель стека корректируется с помощью инструкции push. Таким образом, он копируется в ebp, а параметры помещаются в стек, поэтому они существуют в двух местах: в стеке function и в стеке printf. push es влияют на esp, поэтому ebp копируется.

0 голосов
/ 28 марта 2014

Если вы хотите изучать ассемблер и разбирать двоичные файлы, вам может пригодиться ODA. Это веб-дизассемблер, который удобен для разборки множества различных архитектур без необходимости создания objdump для binutil для каждой из них.

http://onlinedisassembler.com/

0 голосов
/ 16 февраля 2012

Вы затронули интересный вопрос, который, я думаю, до сих пор не рассматривался напрямую.Я предполагаю, что вы видели ассемблерный код, который выглядит примерно так:

sub esp, X
...
mov [ebp+Y], eax
call Z

Этот вид дизассемблирования генерируется некоторыми компиляторами.Что он делает, так это расширяет стек, а затем присваивает значение нового пространства eax (которое, мы надеемся, заполнилось чем-то значимым к этому моменту).Это фактически эквивалентно тому, что делает мнемоника push.Я не могу ответить , почему некоторые компиляторы генерируют этот код вместо этого, но я предполагаю, что в какой-то момент выполнение этого способа было сочтено более эффективным.

...