почему в функции gcc "start" (перед main) есть бессмысленный asm-код? - PullRequest
2 голосов
/ 01 ноября 2011

Меня немного интересует, что делает время выполнения, поэтому я пишу простую программу на c, как показано ниже (я не вставляю код some_function. Я думаю, что это не важно.)

int main(int argc, char *argv[]) {
    some_fucntion();
    return;
}

Я использую i686-apple-darwin10-llvm-gcc-4.2 на моем Mac (10.6.8, Intel Core) и компилирую исходный код с помощью следующей команды.На самом деле я попытался использовать O3 и получить тот же результат.

gcc -O0 -o test test.c

Затем я набираю следующую команду и получаю этот код asm.

otool -tV test

Я получаю следующий код asm.Я думаю, что этот код относится к подготовке аргументов для основной функции.Но я до сих пор не могу понять, почему существует цикл для установки значения eax на 0x00?А почему есть инструкция "jmp"?поэтому следующая инструкция никогда не будет выполнена, верно?

Буду очень признателен, если кто-нибудь сможет объяснить здесь весь код asm.Спасибо.

start:
0000000100000d20        pushq   $0x00
0000000100000d22        movq    %rsp,%rbp
0000000100000d25        andq    $0xf0,%rsp
0000000100000d29        movq    0x08(%rbp),%rdi
0000000100000d2d        leaq    0x10(%rbp),%rsi
0000000100000d31        movl    %edi,%edx
0000000100000d33        addl    $0x01,%edx
0000000100000d36        shll    $0x03,%edx
0000000100000d39        addq    %rsi,%rdx
0000000100000d3c        movq    %rdx,%rcx
0000000100000d3f        jmp     0x100000d45
0000000100000d41        addq    $0x08,%rcx
0000000100000d45        cmpq    $0x00,(%rcx)
0000000100000d49        jne     0x100000d41
0000000100000d4b        addq    $0x08,%rcx
0000000100000d4f        callq   _main
0000000100000d54        movl    %eax,%edi
0000000100000d56        callq   0x100000e7c     ; symbol stub for: _exit
0000000100000d5b        hlt
0000000100000d5c        nop

1 Ответ

5 голосов
/ 01 ноября 2011
start:
0000000100000d20        pushq   $0x00               ; push NULL (end of dynamic frame pointer chain)
0000000100000d22        movq    %rsp,%rbp           ; set frame pointer
0000000100000d25        andq    $0xf0,%rsp          ; align stack
0000000100000d29        movq    0x08(%rbp),%rdi     ; mov argc to 1st arg
0000000100000d2d        leaq    0x10(%rbp),%rsi     ; mov argv to 2nd arg
0000000100000d31        movl    %edi,%edx           ; \
0000000100000d33        addl    $0x01,%edx          ; > 3rd arg = argv + (argc + 1) * 8
0000000100000d36        shll    $0x03,%edx          ; > = envp
0000000100000d39        addq    %rsi,%rdx           ; /
0000000100000d3c        movq    %rdx,%rcx           ; \
0000000100000d3f        jmp     0x100000d45         ; >
0000000100000d41        addq    $0x08,%rcx          ; > find 1st NULL after envp and
0000000100000d45        cmpq    $0x00,(%rcx)        ; > move to 4th arg
0000000100000d49        jne     0x100000d41         ; /
0000000100000d4b        addq    $0x08,%rcx          ; and add 8 (apple)
0000000100000d4f        callq   _main               ; call main
0000000100000d54        movl    %eax,%edi           ; move return value to 1st arg
0000000100000d56        callq   0x100000e7c         ; and call _exit (doesn't return)
0000000100000d5b        hlt
0000000100000d5c        nop

apple - это специфический для Apple аргумент, который содержит путь к исполняемому файлу ( source ).

...