目录
5.利用命令“g/\.s*/d”精简20222802.s文件
一、汇编一个C语言程序并分析指令执行过程
1.CPU寄存器和汇编的基础知识点
●16位、32位、64位的CPU寄存器名称有所不同,比如指令地址寄存器ip,在16位中叫ip,32位中叫eip,64位叫rip
●32位的汇编指令通常以l结尾,比如movl相当于mov的含义
●ebp : 堆栈基地址寄存器,这个寄存器保存的是当前执行绪的栈底地址
●esp : 堆栈栈顶寄存器,这个寄存器保存的是当前执行绪的栈顶地址
●eip : 指令地址寄存器,这个寄存器保存的是指令所在的地址,CPU会不断的根据eip所指向的指令去内存取指令并执行,并自行累加取下一条指令逐条执行。eip无法直接赋值,call、ret、jmp等指令可以起到修改eip的作用
●%用于直接寻址寄存器,$用于表示立即数。movl $8, %eax表示把立即数8存到eax中
●()用于内存间接寻址,比如movl $10, (%esp)表示将立即数10保存到esp所指向的内存地址中
●8(%ebp)表示先找到 ebp所指向的地址值+8后得到的地址
●栈地址值是向下增长的,即栈顶从高地址向低地址移动
2.创建20222802.c文件,编写代码
3.编译20222802.c文件,查看程序返回值
4.将c文件编译成汇编文件,查看20222802.s文件
5.利用命令“g/\.s*/d”精简20222802.s文件
6.汇编代码分析
g:
pushl %ebp //将ebp的值压入栈内
movl %esp, %ebp //将ebp寄存器同样指向esp寄存器指向的那块栈地址
movl 8(%ebp), %eax //将15压入eax栈中
addl $13, %eax //执行15+13
popl %ebp
ret
f:
pushl %ebp //分配新的栈空间
movl %esp, %ebp
subl $4, %esp
movl 8(%ebp), %eax //将8(%ebp寄存器的内容压入eax栈中
movl %eax, (%esp) //将eax寄存器中的内容存入(%esp)寄存器中
call g //调用g函数
leave
ret
main: //开始执行
pushl %ebp //esp沿着地址递减的方向指向下一个存储单元,将ebp现在指向的存储 //单元的地址压入栈中
movl %esp, %ebp //将ebp寄存器同样指向esp寄存器指向的那块栈地址
subl $4, %esp //将esp寄存器的内容减4,向下一个帧移动
movl $15, (%esp) //立即数15入栈
call f //调用f函数
addl $1, %eax //返回值+1
leave
ret
7.总结
1. 计算机是如何工作的:
从硬件的角度:CPU通过总线和内存连接,CPU从IP所指的代码段取指令执行;
从程序员的角度:内存负责保存指令,CPU负责执行指令。
2. CPU怎么识别,识别什么样的指令:
API 程序员与计算机的接口;ABI 程序与CPU的接口。
3. 约定指令是用什么寄存器
x86计算机中,eip是自加一的指向一个指令,自加一是加一条指令,而非字节等,eip还可以被其他指令修改,如跳转调用指令。
CPU在实际取指令时根据CS:eip来准确定位一个指令。
4. linux内核使用的是AT&T汇编格式