1.实验简介
冯·诺依曼体系结构由运算器、存储器、控制器和IO设备等组成。指令和数据一般存放在存储器中。当我们写的程序运行时,操作系统通过总线将代码和指令一行一行地从内存中读入到CPU中执行。CPU中有很多寄存器,比如IP,esp,edp等。下面通过一个简单的实验来分析汇编代码执行过程。
2.实验部分
2.1 实验环境
64位Linux虚拟机环境下实验
2,2 简单的c语言代码(main.c)
int g(int x)
{
return x + 1;
}
int f(int x)
{
return g(x);
}
int main(void)
{
return f(5) + 1;
}
2.3 在Linux虚拟机终端执行命令
gcc –S –o main.s main.c -m32
2.3 分析生成的汇编代码
%eax:默认“累加器”,也是一个通用寄存器,往往也是存储函数返回值的寄存器。
%esp:“基址指针”,一般作为一个函数的框架指针;
%ebp:堆栈指针,典型的用法是配合push和pop汇编指令间接改变自身,%ebp就是栈顶指针;
g:
pushl %ebp //把ebp压栈
movl %esp, %ebp //将esp的值赋给ebp
movl 8(%ebp), %eax //变址寻址ebp+8,对应值赋值给eax
addl $1, %eax //eax中,5+1=6
popl %ebp //ebp弹栈
ret //退出,返回调用指令的下一条
f:
pushl %ebp //把ebp压栈
movl %esp %ebp //将esp的值赋给ebp
movl 8(%ebp) //变址寻址ebp+8
call g //将eip压栈,并修改其值为g函数,调用g函数开始执行
addl $4, %esp //esp移动四个位置
leave //相当于两个指令movl %ebp, %esp; popl %edp
ret //退出,popl eip
main:
pushl %ebp //把ebp压栈
movl %esp %ebp //将esp的值赋给ebp
pushl $5 //将5压栈
call f //调用f函数
addl $4, %esp //esp移动四个位置
addl $1, %eax //eax值加一
leave //相当于两个指令movl %ebp, %esp; popl %edp
ret ///退出,popl eip
当程序运行时,操作系统使用eip寄存器通过总线将代码和指令一行一行地从内存中读入到CPU中执行。在程序运行的过程中,通过函数调用等手段可以改变eip中的值来改变指令的执行顺序,同时有esp、ebp、eax等重要的寄存器完成指令的执行。汇编语言是介于高级语言和机器语言之间方便计算机进行程序执行的语言,学习汇编语言有利于加深我们对计算机的理解。