Как интерпретировать этот кусок сборки? - PullRequest
0 голосов
/ 21 апреля 2020

Я должен был скомпилировать эту c программу, которая, как говорят, низкого качества, и помнить, что я использую старую виртуальную машину IA-32 с архитектурой. Эта программа большую часть времени возвращает ошибку сегментации, и я должен ее отладить. Я очень новичок в сборке, и я понимаю, что каждая инструкция делает на уровне стека, например, я знаю, что делают lea, sub, push et c. Моя трудность заключается в том, чтобы понять, какой части моей программы C она соответствует и почему они выполняются.

Это программа:

char *getline() { 
    char buf[8]; 
    char *result; 
    gets(buf); 
    result = malloc(strlen(buf)); 
    strcpy(result, buf); 
    return result ; 
} 

void main () {
    getline();
}

Я скомпилировал этот файл, используя gcc -O0 -g, а затем использовал gdb для этого исполняемого файла и разбирал getline и main по отдельности. Это вывод для getline:

0x08048400 <getline+0>: push   %ebp
0x08048401 <getline+1>: mov    %esp,%ebp
0x08048403 <getline+3>: sub    $0x18,%esp
0x08048406 <getline+6>: sub    $0xc,%esp
0x08048409 <getline+9>: lea    0xfffffff8(%ebp),%eax
0x0804840c <getline+12>:    push   %eax
0x0804840d <getline+13>:    call   0x8048304
0x08048412 <getline+18>:    add    $0x10,%esp
0x08048415 <getline+21>:    sub    $0xc,%esp
0x08048418 <getline+24>:    lea    0xfffffff8(%ebp),%eax
0x0804841b <getline+27>:    push   %eax
0x0804841c <getline+28>:    call   0x8048324
0x08048421 <getline+33>:    add    $0x4,%esp
0x08048424 <getline+36>:    push   %eax
0x08048425 <getline+37>:    call   0x8048314
0x0804842a <getline+42>:    add    $0x10,%esp
0x0804842d <getline+45>:    mov    %eax,0xfffffff4(%ebp)
0x08048430 <getline+48>:    sub    $0x8,%esp
0x08048433 <getline+51>:    lea    0xfffffff8(%ebp),%eax
0x08048436 <getline+54>:    push   %eax
0x08048437 <getline+55>:    pushl  0xfffffff4(%ebp)
0x0804843a <getline+58>:    call   0x8048344
0x0804843f <getline+63>:    add    $0x10,%esp
0x08048442 <getline+66>:    mov    0xfffffff4(%ebp),%eax
0x08048445 <getline+69>:    leave  
0x08048446 <getline+70>:    ret    

main:

0x08048447 <main+0>:    push   %ebp
0x08048448 <main+1>:    mov    %esp,%ebp
0x0804844a <main+3>:    sub    $0x8,%esp
0x0804844d <main+6>:    and    $0xfffffff0,%esp
0x08048450 <main+9>:    mov    $0x0,%eax
0x08048455 <main+14>:   sub    %eax,%esp
0x08048457 <main+16>:   call   0x8048400 <getline>
0x0804845c <main+21>:   leave  
0x0804845d <main+22>:   ret    

Как я уже сказал, я понимаю саму сборку, я просто не понимаю цели всех инструкции. Первые две и две последние инструкции объяснять не нужно, потому что я понимаю. (Мне нужна только помощь с getline сборкой, а не main). Мои трудности в основном таковы:

1- sub инструкции - я понимаю, что вы выделяете место в стеке, но почему это так много места и какой части кода C это соответствует к?

2- Что именно делает lea? Он помещает значение в %eax, каково значение этого значения и почему оно добавляется после, для сохранения?

3 - Все ли инструкции push предназначены только для сохранения содержимого регистры перед вызовом функции или у них другое назначение?

...