x86函數調用棧分析

聲明:原創作品轉載請註明出處

參考文檔:《Linux內核分析》MOOC課程 http://mooc.study.163.com/course/USTC-1000029000

 

本文將以一個C代碼片段來刨析x86函數調用棧變化過程,進而理解高級語言是如何在計算機上運行的。

C代碼片段如下:

int g(int x)
{
    return x+30;
}

int f(int x)
{
    return g(x);
}

int main(void)
{
    return f(28) + 100;
}

衆所周知,計算機不能直接執行高級語言,高級語言必須通過編譯器翻譯成彙編代碼,再通過彙編器翻譯成二進制代碼,最後鏈接爲可執行程序,方可在計算機上執行,目前使用最多的編譯器是gcc,故使用gcc -S -o main.s main.c -m32命令,將C代碼翻譯成相應的彙編代碼。

g:
	pushl	%ebp
	movl	%esp, %ebp
	movl	8(%ebp), %eax
	addl	$30, %eax
	popl	%ebp
	ret
f:
	pushl	%ebp
	movl	%esp, %ebp
	subl	$4, %esp
	movl	8(%ebp), %eax
	movl	%eax, (%esp)
	call	g
	leave
	ret
main:
	pushl	%ebp
	movl	%esp, %ebp
	subl	$4, %esp
	movl	$28, (%esp)
	call	f
	addl	$100, %eax
	leave
	ret

好了,準備工作做完了,下面就讓我們從熟悉的main()開始一步步分析函數調用棧的變化吧?

我們假設調用main()之前,函數調用棧如下:

當執行下面語句後,

main:
    pushl %ebp

函數調用棧如下:

當執行下面語句後,

main:
    ....
    movl %esp, %ebp

函數調用棧如下:

當執行下面語句後,

main:
    ....
    subl $4, %esp

函數調用棧如下:

當執行下面語句後,

main:
    ....
    movl $28, (%esp)

函數調用棧如下:

由於call  f相當於pushl %eip,movl f %eip,所以當執行下面語句後,

main:
    .....
    call f

函數調用棧如下:

當執行下面語句後,

f:
    pushl %ebp

函數調用棧如下:

當執行下面語句後,

f:
    .....
    pushl %esp, %ebp

函數調用棧如下:

當執行下面語句後,

f:
    .....
    subl $4, %esp

函數調用棧如下:

當執行下面語句後,

f:
    .....
    movl 8(%ebp), %eax

函數調用棧如下:

當執行下面語句後,

f:
    .....
    movl %eax, (%esp)

函數調用棧如下:

當執行下面語句後,

f:
    .....
    call g

函數調用棧如下:

當執行下面語句後,

g:
    pushl %ebp

函數調用棧如下:

當執行下面語句後,

g:
    ....
    movl %esp, %ebp

函數調用棧如下:

當執行下面語句後,

g:
    ....
    movl 8(%ebp), %eax

函數調用棧如下:

當執行下面語句後,

g:
    ....
    addl $30, %eax

函數調用棧如下:

當執行下面語句後,

g:
    ....
    popl %ebp

函數調用棧如下:

由於ret語句相當於popl %eip,所以當執行下面語句後,

g:
    ....
    ret

函數調用棧如下:

由於leave語句相當於movl %ebp %esp,popl %ebp,所以當執行下面語句後,

f:
    ....
    leave

函數調用棧如下:

由於ret語句相當於popl %eip,所以當執行下面語句後,

f:
    ....
    ret

函數調用棧如下:

當執行下面語句後,

main:
    ....
    addl $100, %eax

函數調用棧如下:

由於leave語句相當於movl %ebp %esp,popl %ebp,所以當執行下面語句後,

main:
    ....
    leave

函數調用棧如下:

main()中ret語句將eip返回至操作系統,至此,函數調用棧變化過程分析完成!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章