语言的演变-汇编到c语言的演变

语言的演变-汇编到c语言的演变
汇编到c语言的最多变化在于,以函数为单位的调用关系。
那么这个调用关系在汇编下是怎么体现的呢?
具体来说:c语言的函数关系在汇编下变成了什么?
栈就是这个变化的关键,对的变化就体现了函数的调用关系。
没一个新函数的调用意味这一个新栈的建立。
一个函数调用的结束有就伴随这栈的结束。
关于函数的调用和返回,这里解释一下以下几个命令。

  1. call :大家都指针,指令的执行,无非就是指针寄存器指向一个新的位置。那么该语句的价值就是ip指向了新的位置。要调用的函数的入口。在指向之前还吧当前的指向入栈,因为一会这个函数调用完了,还要继续向下执行呢,所以这里将旧函数的ip入栈。
  2. ret :该语句只做一件事就是,将旧堆中旧的ip地址在设置为当前的ip地址,目的继续执行之前函数的指令。这两条指令的主要价值就是切换指令执行的指针。
  3. leave:结束这个条指令执行之前,先应该解释一下下面的知识点。
    函数调用和栈的创建。
    对一个栈的描述用如下两个寄存器。
    ebp:基指针寄存器
    esp:栈指针寄存器
    他们倆如何描述栈呢:ebp做为基地址。esp指向向对应当前基地址的偏移。
    就这么说吧,有ebp到esp的这段空间就叫做栈空间。
    下面说说函数调用中bp和sp是如何变化的呢?
    如果一个函数调用开始了,那么这个函数最先的两条指令就是
    pushl %ebp
    movl %esp, %ebp
    解释一下:
    pushl :向栈中写入数据,写如的内容就是后面的参数,这里明显是将ebp的址入栈,这时候栈定是该栈的栈底的地址。
    movl:将 前面参数的内容保存到后面的参数里,这里是将esp执行的地址给了ebp,ebp被赋值意味这一个新的栈被创建了。到这里,旧函数的栈顶保存了自己栈底的地址。新的函数在之后创建了一个新栈。这时候栈顶和栈底指向的空间是相同的。栈还没有写入任何内容。
    这里ebp没有变化,但是ebp变成了一个新的地址,哦其实ebp也变了?
    什么变了呢?意义变了,之前代表的是旧栈的栈顶,现在代表的是新栈的栈顶。
    新函数创建新栈的过程讲完了,那么退栈的过程是什么样的呢。
    函数调用完了就会把用完看空间收回,函数执行到最后的时候一定是和刚建完栈的情况相同。
    这时候要回到旧函数,用旧栈继续运行。
    退栈的指令就是 leave。
    leave等同于如下指令
    movl %ebp, %esp
    pop %ebp
    比一下和创建栈的指令有啥不一样。
    pushl %ebp
    movl %esp, %ebp
    完全相反。
    结果我不用多解释了,就是退栈,回复到旧栈的状态。
    movl %ebp, %esp :ebp保存的是啥,是新栈的栈低,旧栈的栈顶,esp变成了旧栈的esp。
    pop %ebp:这里大家知道,函数调用的时候,栈顶保存的是栈底的地址,这里将该地址弹出,赋值给ebp就是回复了旧栈的状态。
    前面讲过,在用ret 换一下eip指针的执行,就有开始了旧函数的接续运行。
    好了函数的调用和返回过程将完了,无论调用多少次,无论多少成的嵌套都是这样的一个调用过程。
    有没有豁然开朗的感觉呢。
    关于语言的升级,这是走出这一部的关键。
    这就是汇编向c跨进重要的一步。
    呵呵,有历史意义的一部,你一定要了解哦。

猜你喜欢

转载自blog.csdn.net/xie__jin__cheng/article/details/89212655