Анализ кода сборки, сгенерированного для манипулирования аргументами командной строки - PullRequest
3 голосов
/ 28 февраля 2012
#include <stdio.h>
int main(int argc, char * argv[])
{
 argv[1][2] = 'A';
 return 0;
}

Вот соответствующий ассемблерный код от GCC для 32-битной архитектуры Intel. Я не могу полностью понять, что происходит.

main:
        leal    4(%esp), %ecx  - Add 4 to esp and store the address in ecx
        andl    $-16, %esp  - Store first 28 bits from esp's address into esp??
        pushl   -4(%ecx)  - Push the old esp on stack
        pushl   %ebp         - Preamble
        movl    %esp, %ebp
        pushl   %ecx          - push old esp + 4 on stack
        movl    4(%ecx), %eax   - move ecx + 4 to eax. this is the address of argv. argc stored at (%ecx).
        addl    $4, %eax - argv[1]
        movl    (%eax), %eax - argv[1][0]
        addl    $2, %eax  - argv[1][2]
        movb    $65, (%eax) - move 'A'
        movl    $0, %eax - move return value (0)
        popl    %ecx - get old value of ecx
        leave
        leal    -4(%ecx), %esp  - restore esp
        ret

Что происходит в начале кода перед преамбулой? Где находится магазин argv согласно следующему коду? В стеке?

Ответы [ 2 ]

5 голосов
/ 28 февраля 2012

Забавный код (первые две строки), который вы видите, - это выравнивание стека до 16 байтов (-16 соответствует ~15, а x & ~15 округляет x до кратного 16).

argv будет храниться в ESP + 8 при входе в функцию. leal 4(%esp), %ecx создает указатель на псевдоструктуру, содержащую argc и argv, а затем переходит к ним оттуда. movl 4(%ecx), %eax доступ argv из этой псевдоструктуры.

1 голос
/ 28 февраля 2012

argv является параметром для main (), поэтому во многих ABI он действительно будет передаваться в стеке.

...