程序设计入门学的是C语言,但是当时在学习的时候,对于程序在运行时内部到底是怎样在运行十分的疑惑,特别是在学习函数的时候,总是想知道,在底层(内存/cpu)程序到底是怎么完成运行的。一直都知道堆栈0是函数调用,程序运行中十分中要的一个部分,也知道,堆栈用于暂时存储数据,但是一直这个部分的认识比较模糊。
- 汇编中的子程序调用(对应的高级语言的部分-函数嗲用)
call 子程序的名字:执行到这里,cpu 会做两件事。一是保存,二是跳转
1.保存:ip 指令指针。如果是段内跳转。会将当前的ip 偏移值压入栈。如果是段间跳转,会将cs 段寄存器的段地址,和ip 指令指针(偏移值) 压入栈中
2.跳转:根据子程序的名字跳转到指定的位置 - 子程序的格式
1.名字 pro 程序入口
2.内容 将在这个子程序中会使用到的寄存器压入栈中(在程序结束时要将寄存器弹出栈)
3.在程序执行结束,子程序末尾:ret 表达式【段内是ret 段间是retf】
子程序名字 endp - 程序执行结束后,堆栈会将要入栈的cs 和ip 弹出栈。让程序返回调用处继续向下执行。
关于ret 后面的表达式 :会改变栈的指针,也就是在CS 和IP 都被弹出站后,表达式的值就是栈的指针SP 还要移动的字节数
关于参数:
1.使用就寄存器来传递
2.在调用子程序之前先将参数压入栈中
理解了汇编中子程序的调用,再返回来看高级语言中函数的调用就不难了。在高级语言中定义了函数名是函数的起始地址。所以在调用函数时,都会使用函数名,其实就是相当于跳转目的地址,在堆栈中存放的是在函数调用中的临时变量,存放的函数执行完之后继续执行的地址
形象一点的比喻:函数就相当于游戏中的一个任务,当你要去执行这个任务时,就要跳到对应的位置,但是同时,系统要记住你现在的位置,和你执行完这个函数后下一个要做的事。函数的参数就相当于你的背包,里面会记录你产生的各种数,当你结束这个任务之后,你的背包里只有这个任务的结果。根据系统的记录返回你跳转的地方继续执行下一步