У меня есть вопрос о структуре стека кадров? - PullRequest
2 голосов
/ 11 апреля 2011

Я новичок в изучении сборки. я пишу файл c:

#include <stdlib.h>

int max( int c )
{
        int d;
        d = c + 1;

        return d;
}

int main( void )
{
        int a = 0;
        int b;
        b = max( a );

        return 0;
}

и я использую gcc -S as01.c и создаю файл сборки.

        .file   "as01.c"
        .text
.globl max
        .type   max, @function
max:
        pushl   %ebp
        movl    %esp, %ebp
        subl    $32, %esp
        movl    $0, -4(%ebp)
        movl    $1, -24(%ebp)
        movl    $2, -20(%ebp)
        movl    $3, -16(%ebp)
        movl    $4, -12(%ebp)
        movl    $6, -8(%ebp)
        movl    8(%ebp), %eax
        addl    $1, %eax
        movl    %eax, -4(%ebp)
        movl    -4(%ebp), %eax
        leave
        ret
        .size   max, .-max
.globl main
        .type   main, @function
main:
        pushl   %ebp
        movl    %esp, %ebp
        subl    $20, %esp
        movl    $0, -4(%ebp)
        movl    -4(%ebp), %eax
        movl    %eax, (%esp)
        call    max
        movl    %eax, -8(%ebp)
"as01.s" 38L, 638C          

я в замешательстве, потому что movl %eax, -4(%ebp) movl -4(%ebp), %eax в max (), я знаю, что% eax используется для возврата значения любой функции. Я думаю, что% eax - это временная регистрация для магазина c + 1. Это правильно? спасибо за ваш ответ.

Ответы [ 2 ]

4 голосов
/ 11 апреля 2011

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

Код фактически разбивается на:

    pushl   %ebp
    movl    %esp, %ebp
    subl    $32, %esp

Стандартный пролог функции, установка нового фрейма стека и резервирование 50 байтов для фрейма стека.

    movl    $0, -4(%ebp)
    movl    $1, -24(%ebp)
    movl    $2, -20(%ebp)
    movl    $3, -16(%ebp)
    movl    $4, -12(%ebp)
    movl    $6, -8(%ebp)

Заполнить кадр стека фиктивными значениями (предположительно, в качестве средства отладки).

    movl    8(%ebp), %eax
    addl    $1, %eax
    movl    %eax, -4(%ebp)

Считать параметр c из стекового фрейма, добавить к нему один, сохранить его в (другом) слоте стека.

    movl    -4(%ebp), %eax
    leave
    ret

Считать значение обратно из слота стека и вернуть его.

Если вы скомпилируете это с оптимизацией, вы увидите, что большая часть кода исчезнет. Если вы используете -fomit-frame-pointer -Os, вы должны получить следующее:

max:
    movl    4(%esp), %eax
    incl    %eax
    ret
0 голосов
/ 11 апреля 2011
    movl    %eax, -4(%ebp)

Здесь значение, вычисленное для d (теперь хранится в eax), сохраняется в ячейке памяти d.

    movl    -4(%ebp), %eax

В то время как здесь загружается возвращаемое значение (d)в eax, потому что, как вы знаете, eax содержит возвращаемое значение функции.
Как сказал @David, вы компилируете без оптимизации, поэтому gcc генерирует простой в отладке код, который довольно неэффективен иповторяющиеся иногда.

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