簡體   English   中英

從C代碼了解x86匯編代碼

[英]Understanding x86 Assembly Code from C code

C代碼:

#include <stdio.h>

main() {
    int i;
    for (i = 0; i < 10; i++) {
        printf("%s\n", "hello");
    }
}

ASM:

    .file   "simple_loop.c"
    .section    .rodata
.LC0:
    .string "hello"
    .text
    .globl  main
    .type   main, @function
main:
.LFB0:
    .cfi_startproc
    pushl   %ebp # push ebp onto stack
    .cfi_def_cfa_offset 8
    .cfi_offset 5, -8
    movl    %esp, %ebp # setup base pointer or stack ?
    .cfi_def_cfa_register 5
    andl    $-16, %esp # ? 
    subl    $32, %esp # ?
    movl    $0, 28(%esp) # i = 0
    jmp .L2
.L3:
    movl    $.LC0, (%esp) # point stack pointer to "hello" ?
    call    puts # print "hello"
    addl    $1, 28(%esp) # i++
.L2:
    cmpl    $9, 28(%esp) # if i < 9
    jle .L3              # goto l3
    leave
    .cfi_restore 5
    .cfi_def_cfa 4, 4
    ret

所以我試圖提高我對x86匯編代碼的理解。 對於上面的代碼,我標記了我認為我理解的內容。 至於標記內容的問題,有人可以分享一些亮點嗎? 另外,如果我的任何評論都沒有,請告訴我。

andl    $-16, %esp # ? 
subl    $32, %esp # ?

這在堆棧上保留了一些空間。 首先, andl指令將%esp寄存器向下andl入到16字節的下一個最低倍數(練習:找出-16的二進制值是什么)。 然后, subl指令將堆棧指針向下移動一點(32字節),保留更多空間(下一步將使用它)。 我懷疑這種舍入是完成的,因此通過%esp寄存器進行訪問會稍微提高效率(但是你必須檢查處理器數據表以找出原因)。

movl    $.LC0, (%esp) # point stack pointer to "hello" ?

這將字符串"hello"地址放在堆棧上(該指令不會更改%esp寄存器本身的值)。 顯然,您的編譯器認為將數據直接移動到堆棧更有效,而不是使用push指令。

暫無
暫無

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

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