2016-11-30 113 views
1

我想了解彙編代碼。我停留在指針被分配的部分和所述代碼之後leaq命令瞭解x86-64中的指針分配彙編代碼

這是我的C代碼:

#include <stdio.h> 
#include<stdlib.h> 

int main(){ 
    int x=50; 
    int *y=&x; 
    return 0; 
} 

這是我的對應彙編代碼:

.file "AssemlyCode.c" 
    .def __main; .scl 2; .type 32; .endef 
    .text 
    .globl main 
    .def main; .scl 2; .type 32; .endef 
    .seh_proc main 
main: 
    pushq %rbp 
    .seh_pushreg %rbp 
    movq %rsp, %rbp 
    .seh_setframe %rbp, 0 
    subq $48, %rsp 
    .seh_stackalloc 48 
    .seh_endprologue 
    call __main 
    movl $50, -12(%rbp) 
    leaq -12(%rbp), %rax 
    movq %rax, -8(%rbp) 
    movl $0, %eax 
    addq $48, %rsp 
    popq %rbp 
    ret 
    .seh_endproc 
    .ident "GCC: (GNU) 5.4.0" 
+0

'int y =&x;'無效。 'y'不是指針 –

+0

對不起,我在編寫代碼時犯了一個菜鳥錯誤.....我現在已經糾正了它 – BrainsOfSteel

+0

更容易閱讀示例:將指針傳遞給本地到外部函數。然後,您可以啓用優化,而無需優化一切。 [請參閱Godbolt編譯器資源管理器中的source + asm](https://godbolt.org/g/N6ESby),它刪除所有設置目標文件元數據的'.seh_'和其他指令。 –

回答

6
leaq -8(%rbp), %rax 
    movl %eax, -4(%rbp) 
    movl $0, %eax 
    addq $48, %rsp 
    popq %rbp 
    ret 
  1. leaq將變量x的地址保存在堆棧上登記rax。變量x是堆棧中的自動變量,因此它的地址計算方式是從保存堆棧幀指針的寄存器(rbp)開始偏移。

  2. movl eax堆棧保存argc參數到堆棧。

  3. 下一步驟是把返回值寄存器eaxmain函數(返回0)

  4. 兩個下操作碼爲函數結尾 - 你正在清理使用棧和恢復先前幀指針寄存器。

  5. 最後一條指令是簡單返回。

+0

可能很好的指出爲什麼rbp-8是'&x':因爲它在堆棧中。我不確定OP不知道哪一部分,不管它是[LEA的](http://stackoverflow.com/questions/1658294/whats-the-purpose-of-the-lea-instruction),還是爲什麼使用*這種方式*。 –

+0

@PeterCordes,謝謝,補充說明。 – user1641854