gcc - 为什么gcc "start"函数(在main之前)中有无意义的asm代码?

标签 gcc assembly llvm

我对运行时的作用有点感兴趣,所以我编写了一个简单的c程序,如下所示。(我没有粘贴some_function的代码。我认为这不重要。)

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

我在 Mac(10.6.8,Intel Core)上使用 i686-apple-darwin10-llvm-gcc-4.2 并使用以下命令编译源代码。实际上我尝试过使用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

最佳答案

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 ) 的路径。

关于gcc - 为什么gcc "start"函数(在main之前)中有无意义的asm代码?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7965094/

相关文章:

gcc - 在 PIC32 (MIPS32) 上运行的 C++

c++ - x86-64 Linux NASM。在 C++ 文件中声明为函数的类型 int 数组的函数参数传递

compilation - 简介 LLVM 通过 Clang

c++ - gcc -Wshadow 太严格了?

c++ - 如何为ns2.35添加反义协议(protocol)?

c++ - 微小的 SSE addpd 循环比 AMD Phenom II 上的标量稍慢?

ios - clang : error: clang frontend command failed with exit code 70 (use -v to see invocation)

haskell - llvm-general 的 cabal 安装失败

gcc - printf 在使用较旧 gcc 的 x86-64 Linux 上陷入 AL = 10 的无限循环

汇编语言 : cbw