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返回至操作系统,至此,函数调用栈变化过程分析完成!

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