簡體   English   中英

GCC生成組裝

[英]GCC generated assembly

為什么printf函數會導致序言的變化?

C code_1:

#include <cstdio>

int main(){
  int a = 11;
  printf("%d", a);
}

GCC -m32生成一個:

.LC0:
        .string "%d"
main:
        lea     ecx, [esp+4]           // What's purpose of this three
        and     esp, -16               // lines?
        push    DWORD PTR [ecx-4]      // 
        push    ebp
        mov     ebp, esp
        push    ecx
        sub     esp, 20                // why sub 20?
        mov     DWORD PTR [ebp-12], 11
        sub     esp, 8
        push    DWORD PTR [ebp-12]
        push    OFFSET FLAT:.LC0
        call    printf
        add     esp, 16
        mov     eax, 0
        mov     ecx, DWORD PTR [ebp-4]
        leave
        lea     esp, [ecx-4]
        ret

C code_2:

#include <cstdio>

int main(){
  int a = 11;
}

GCC -m32:

main:
        push    ebp
        mov     ebp, esp
        sub     esp, 16
        mov     DWORD PTR [ebp-4], 11
        mov     eax, 0
        leave
        ret

在第一個代碼中添加前三行的目的是什么? 如果可以,請解釋第一個匯編代碼。

編輯:

64位模式:

.LC0:
        .string "%d"
main:
        push    rbp
        mov     rbp, rsp
        sub     rsp, 16
        mov     DWORD PTR [rbp-4], 11
        mov     eax, DWORD PTR [rbp-4]
        mov     esi, eax
        mov     edi, OFFSET FLAT:.LC0
        mov     eax, 0
        call    printf
        mov     eax, 0
        leave
        ret

洞察力是編譯器在函數調用時保持堆棧對齊。
對齊是16字節。

lea     ecx, [esp+4]           ;Save original ESP to ECX (ESP+4 actually)
and     esp, -16               ;Align stack on 16 bytes (Lower esp)

push    DWORD PTR [ecx-4]      ;Push main return address (Stack at 16B + 4)
                               ;My guess is to aid debugging tools that expect the RA
                               ;to be at [ebp+04h]
push    ebp
mov     ebp, esp               ;Prolog (Stack at 16B+8)

push    ecx                    ;Save ECX (Original stack pointer) (Stack at 16B+12)

sub     esp, 20                ;Reserve 20 bytes (Stack at 16B+0, ALIGNED AGAIN)
                               ;4 for alignment + 1x16 for a variable (variable space is
                               ;allocated in multiple of 16)

mov     DWORD PTR [ebp-12], 11 ;a = 11

sub     esp, 8                 ;Stack at 16B+8 for later alignment
push    DWORD PTR [ebp-12]     ;a
push    OFFSET FLAT:.LC0       ;"%d"     (Stack at 16B)
call    printf
add     esp, 16                ;Remove args+pad from the stack (Stack at 16B)

mov     eax, 0                 ;Return 0

mov     ecx, DWORD PTR [ebp-4] ;Restore ECX without the need to add to esp
leave                          ;Restore EBP

lea     esp, [ecx-4]           ;Restore original ESP
ret

我不知道為什么編譯器在ecx而不是esp保存esp+4esp+4main的第一個參數的地址)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM