2013-04-13 3 views
2

Я пытаюсь убрать код сборки для моей программы c, которую я получил из gdb, разобрать, не могли бы вы мне помочь.Понимание сборки, изготовленной gdb

мой с код:

#include <unistd.h> 



int main(int argc, char *argv[]) 

{ 

char buff[100]; 

/*if no argument…*/ 

if(argc <2) 

{ 

    printf("Syntax: %s <input string>\n", argv[0]); 

    exit (0); 

    } 

    strcpy(buff, argv[1]); 

    return 0; 

} 

и код сборки для моей основной функции:

Свалки ассемблера для функции главного:

0x08048424 <+0>: push %ebp 
    0x08048425 <+1>: mov %esp,%ebp 
    0x08048427 <+3>: and $0xfffffff0,%esp 
    0x0804842a <+6>: add $0xffffff80,%esp 
    0x0804842d <+9>: cmpl $0x1,0x8(%ebp) 
    0x08048431 <+13>: jg  0x8048454 <main+48> 
    0x08048433 <+15>: mov 0xc(%ebp),%eax 
    0x08048436 <+18>: mov (%eax),%eax 
    0x08048438 <+20>: mov %eax,0x4(%esp) 
    0x0804843c <+24>: movl $0x8048544,(%esp) 
    0x08048443 <+31>: call 0x8048344 <[email protected]> 
    0x08048448 <+36>: movl $0x0,(%esp) 
    0x0804844f <+43>: call 0x8048354 <[email protected]> 
    0x08048454 <+48>: mov 0xc(%ebp),%eax 
    0x08048457 <+51>: add $0x4,%eax 
    0x0804845a <+54>: mov (%eax),%eax 
    0x0804845c <+56>: mov %eax,0x4(%esp) 
    0x08048460 <+60>: lea 0x1c(%esp),%eax 

где часть в выделяет размер buff [100]?

ответ

4

Следующий код

int main(int argc, char *argv[]) 
{ 

char buff[100]; 

запрашивает создание полукокса [100] буфера в стеке. Вот что на самом деле происходит:

;// 1. pushing the base pointer register on the stack 
0x08048424 <+0>: push %ebp 

;// 2. Creating the stack frame. Copying the stack pointer register to the base pointer 
;// register creates a stack frame: an area on the stack where a subroutine 
;// can store local data. 
0x08048425 <+1>: mov %esp,%ebp 

;// 3. Making sure that the stack is aligned to 16 bytes. 
0x08048427 <+3>: and $0xfffffff0,%esp 

;// 4. Making room for 128 bytes (100 as requested would throw off the alignment). 
;// 128 is compatible with your requests and is optimized. 
0x0804842a <+6>: add $0xffffff80,%esp 

Итак, вот ваш буфер создается, на 16-байт выровненных стек. Вы просили 100, компилятор дает вам не менее 100, оптимизируя скорость.

+0

Спасибо, это очень помогло. Я попытался вставить разные входы, и я получаю ошибку сегментации, когда длина строки составляет 112 байт ('perl -e 'print" A "x112''), а не 128 байт, почему? –

+0

@ ZainabJH Если вы объявляете 'char buff [100];' и пытаетесь записать в нем строку длиной 112 символов, вы переполните свой буфер и сотрите все, что после. И так как ваш буфер находится в стеке ... Два факта: 1. Если бы ваш буфер один, компилятор должен был бы только выделить 112 байт (7 * 16). Таким образом, есть и другие вещи вместе с ним (возможно). 2. Стек идет вниз по вашей архитектуре (см. [Эта статья о SO] (http://stackoverflow.com/questions/4560720/why-stack-address-goes-in-decreasing-memory-address)), чтобы вы может переписывать важные вещи (например, «ebp», обратный адрес) ... – Jean

4

Здесь:

add $0xffffff80,%esp 

Это вычитает 128 байт (добавить -128) к ESP (стек регистр указателя).

3

Я думаю, что это он add $0xffffff80,%esp. Перемещение указателя стека, чтобы пространство было доступно внутри функции.

Смежные вопросы