通过汇编一个简单的C程序,分析汇编代码理解存储程序计算机是如何工作的

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等重要的寄存器完成指令的执行。汇编语言是介于高级语言和机器语言之间方便计算机进行程序执行的语言,学习汇编语言有利于加深我们对计算机的理解。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值