ATT汇编leave指令
生活随笔
收集整理的這篇文章主要介紹了
ATT汇编leave指令
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
最近在看c程序的編譯出來的匯編文件,發(fā)現(xiàn)涉及到函數(shù)調(diào)用的地方,在返回時有的時候使用的leave,有的時候直接使用的是popl %ebp。
在AT&T匯編中,leave等效于以下匯編指令:
movl %ebp, %esp
二者的差別就在于是否使用 movl %ebp, %esp。這句的作用是用來恢復(fù)堆棧的棧頂指針,是不是堆棧的棧頂指針沒有變化的時候,
就可以不用恢復(fù),直接使用popl指令了?這個疑惑經(jīng)過驗證被證實了。
原C代碼如下:?? /*stack.c*/?? #include?<stdio.h>?? ?? int?main()?? {?? ????return?0;?? }??
[cpp]?view plaincopy 通過gcc?-S?-o?stack.s?stack.c得到匯編代碼?? ????.file???"stack.c"?? ????.text?? ????.globl??main?? ????.type???main,?@function?? main:?? .LFB0:?? ????.cfi_startproc?? ????pushl???%ebp?? ????.cfi_def_cfa_offset?8?? ????.cfi_offset?5,?-8?? ????movl????%esp,?%ebp?? ????.cfi_def_cfa_register?5?? ????movl????$0,?%eax????/*將返回值保存在eax中*/?? ????popl????%ebp????????/*由于在該函數(shù)中,沒有使用到棧,所以esp未變化,不需要恢復(fù)。*/?? ????.cfi_def_cfa?4,?4?? ????.cfi_restore?5?? ????ret?? ????.cfi_endproc?? .LFE0:?? ????.size???main,?.-main?? ????.ident??"GCC:?(GNU)?4.6.2?20111027?(Red?Hat?4.6.2-1)"?? ????.section????.note.GNU-stack,"",@progbits??
將c代碼修改如下:?? #include?<stdio.h>?? int?main()?? {?? ????int?c?=?1;?? ????return?0;?? }?? 對應(yīng)的匯編代碼如下:?? ????.file???"stack.c"?? ????.text?? ????.globl??main?? ????.type???main,?@function?? main:?? .LFB0:?? ????.cfi_startproc?? ????pushl???%ebp????????/*原堆棧棧頂存放著原棧幀的ebp*/?? ????.cfi_def_cfa_offset?8?? ????.cfi_offset?5,?-8?? ????movl????%esp,?%ebp??/*將原堆棧地址放在ebp中,即新的棧幀的地址*/?? ????.cfi_def_cfa_register?5?? ????subl????$16,?%esp???/*堆棧發(fā)生變化*/?? ????movl????$1,?-4(%ebp)?? ????movl????$0,?%eax?? ????leave???????????/*等效于?movl?%ebp,?esp;?popl?%ebp??首先需要恢復(fù)原棧頂指針,然后再根據(jù)棧頂指針恢復(fù)原棧幀的ebp*/?? ????.cfi_restore?5?? ????.cfi_def_cfa?4,?4?? ????ret?? ????.cfi_endproc?? .LFE0:?? ????.size???main,?.-main?? ????.ident??"GCC:?(GNU)?4.6.2?20111027?(Red?Hat?4.6.2-1)"?? ????.section????.note.GNU-stack,"",@progbits??
以上可以很清楚地看出leave的作用,和什么時候用leave,什么使用可以直接使用popl。
在AT&T匯編中,leave等效于以下匯編指令:
movl %ebp, %esp
popl %ebp
注意:此為32bits 操作系統(tǒng),若為64bits 將使用rbp和rsp 寄存器!
為什么有的時候會使用leave,有的時候直接使用popl %ebp?這個問題一開始我也沒搞懂,后來通過分析堆棧才有點清醒。二者的差別就在于是否使用 movl %ebp, %esp。這句的作用是用來恢復(fù)堆棧的棧頂指針,是不是堆棧的棧頂指針沒有變化的時候,
就可以不用恢復(fù),直接使用popl指令了?這個疑惑經(jīng)過驗證被證實了。
main函數(shù)是一個最特殊的函數(shù)調(diào)用,就以它的調(diào)用過程為準。
[cpp]?view plaincopy
[cpp]?view plaincopy
[cpp]?view plaincopy
總結(jié)
以上是生活随笔為你收集整理的ATT汇编leave指令的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: oracle sqlplus执行脚本_连
- 下一篇: 浅谈malloc,calloc,real