00:00
这是一段C语言的代码,它是怎么让G器运行的呢?比如我们可以使用GCC编译器将源代码先转换成汇编代码,这里的杠S就是生成汇编的参数,杠O2只是优化参数忽略就好了,然后把杠S换转换成杠C,就会产生机器代码,最后和unix库函数代码合并,最终未给CPU去执行。今天我们通过汇编来了解C语言在运行时的站,这里的汇编基于IA32指令集,IA32也就是INTEL32位体系结构,这个处理器系列俗称X86 CPU运行时自己附带有少量的小型存储区域,称为寄存器。在IA32中,寄存器的名字都是E开头的,大部分都是通用的,只有两个比较特殊ESP专门存。
01:00
放指针,而EBP存放真指针。后面会具体介绍一个程序。在运行时,这些局部变量会存储在内存中的区域,称为站。站在数据结构中是一个基本的结构,只有两个操作,一个是push入站,另一个是pop出站。但在内存中,站是倒过来的,也就是从高地指向低地址增长,这样站顶的指针称为站指针,指向站的最下面。这里用寄存器ESP,也就是sta pointer的缩写。举个例子,有三个寄存器,它们存储三个不同的值,0X代表16进制的意思,这里可以忽略有一句汇编是push ex,也就是将寄存器ex中的值入站,这里的air指代long的意思,占四个字节大小,俗称双字。它实际上可以用另外两条汇编等同。现在内存中有一个站ESP,就是站指针指向站顶,地址是0X108,那么第一句话让站指针EP减少四个字节,Dollar符号代表立即数,就是指数字,那么在内存中占指针向下移动四个字节,这里一个单元格是四个字节,注意站士从高地址向低地址伸长。然后第二句再将寄存器ex的值赋值给站指针E。
02:40
SP所指向的内存地址,这里的括号是把寄存器中的值当成内存的地址,根据地址来找到对应的值。那么反过来,POP1DX将站点出站赋值给寄存器EDX等价于这两句话。首先第一句话将站指针EP指向的值0XE03先赋值给寄存器EDX,然后再将站指针ESP向上移动四个字节,原来的值没有必要改变,但已经属于空的区域了。现在我们从这段C程序出发,了解站的运行状态,主函数叫Co,它会调用swap at函数,将两个参数互换再相加,每个运行的基本单位成为过程。这里具体讲是函数Co函数运行时内。
03:40
帧中的运行站里面有一块相应的区域成为战争。当调用swap I的函数前,战争中已经有局部的变量。当前站点由站指针由寄存器ESP存储,主函数对应站帧的起始地址由帧指针也就是寄存器EBP存储。在调用swap a之前,取变量a one和a two的地址作为调用参数。
04:12
我们来看对应的汇编,首先是将EBP减去四的地址给寄存器EXA暂时存储,再将暂存的值压占,也就是a two的地址。同样道理,后两句话是将a one的地址压站,最后用call命令调用swap a保存,调用后下一句代码地址作为返回地址,然后压站。现在正式开始执行swap at函数,首先要创建swap at函数对应的战争。按照汇编,先将寄存器EBP帧指针压站,这里的EBP指向上一个站帧的起始地址,然后将站指针ESP的地址附给帧指针EBP,也就是针指针也指向站顶。
05:08
再把寄存器ebx保存,因为它有可能存有之前函数的变量,接着是swap函数体对应的汇编,这里就不展开了。最后调用结束时通过操纵站指针和真指针恢复到主函数Co继续执行。好了,本期的视频就到这里,我们下期再见。
我来说两句