117-描述函数调用的现场保护和现场恢复

在这里插入图片描述

在这里插入图片描述
首先进入主函数,系统为主函数开辟一个栈帧,依次入栈 x=10(占4字节),y=20(占4字节),z=0(占4字节),执行到z=fun(x,y);调用子函数fun,开辟子函数fun的栈帧,先将y的值赋值给b,b=20入栈,然后将x的值赋值给a,a=10入栈,然后将主函数的栈底指针入栈,然后将主函数z=fun(x,y);后的指令地址也进行入栈,称为现场保护。然后将a+b的值30赋值给c,将c=30入栈。子函数此时执行到return c; 系统将30这个值寄存到eax寄存器中,然后将eax寄存器的值30赋值给主函数的z。然后将z=fun(x,y);的指令地址和主函数的栈底指针恢复给主函数,称为现场恢复,主函数执行printf("%d ",z); return 0;程序结束

在这里插入图片描述
push push src入栈指令 将源操作数src压入堆栈
pop pop dest 出栈指令 从栈顶弹出数据到dest
mov mov dest,src 将数据从src移动到dest
add 加法指令 add dest,src 在dest基础上加src
sub 减法指令 sub dest,src 在dest基础上减src
inc 加1指令 dec减1指令 inc dest在dest基础上加1 dec dest在dest基础上减1
not 取反运算指令 not dest
and 与 or或 xor异或 and dest,src 把dest和src进行与运算后送回到dest or dest,src 把dest和src进行或运算之后送回到dest
loop 计数循环 是ecx的值减1,当ecx的值不为0的时候跳转到label,否则执行loop之后的语句
call 过程调用指令 call label 直接调用label 将当前ip或cs和ip压入栈中 转到label处 不能实现短转移
jmp 无条件转移命令 jmp label 无条件地转移到标号为label的位置
je 条件转移指令 je label zf=1时跳转到标号为label的位置
jne 条件转移指令 je label zf=0时跳转到标号为label的位置
[eax]寄存器间接寻址 eax寄存器直接寻址
ret 用栈中的数据修改ip(近转移)
reft 用栈中的数据修改cs:ip(远转移)
lea 将存储器操作数的4位16进制偏移地址送到指定的寄存器。源操作数必须是存储器操作数,目标操作数必须是16位通用寄存器。该寄存器常用来做地址指针。
rep stos stos串存储指令 将exa中的数据传送到目的地址(默认es:[edi]),
rep重复前缀指令 每执行一次 ecx减1 直到ecx减至0.重复执行结束
rep stos dword ptr es;[edi]; 从低地址向高地址填充
0cccccccch 起到填充的作用 负责把前函数的空间进行清理
在这里插入图片描述
在这里插入图片描述
以上这一列地址都寄存在eip寄存器中
在这里插入图片描述

在这里插入图片描述
也是进行函数调用的现场保护和现场恢复

栈空间从上到下,从低地址向高地址

注意 栈平衡 抬栈 压栈

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/LINZEYU666/article/details/111721477