《汇编语言》王爽,学习笔记(子程序调用)

在栈的那里已经简单提到了子程序的调用的实质,就是修改CS:IP,在这里就详细介绍一下子程序调用的过程。

1.call,ret,retf指令

call,ret和retf是汇编为子程序调用而专门设计的汇编指令,CPU在执行ret和retf指令时,利用的栈中的数据,ret只修改IP的值,实现近转移(段内),而retf修改CS和IP的值(默认CS存在栈中的高位地址),实现远转移(段间)。

CPU在执行ret指令时,进行下面操作,用汇编语法解释就是:

pop IP                          ;将栈顶元素的值赋值给IP,把栈顶向下移动两个字节(删除原栈顶)

而CPU在执行retf指令时,进行下面操作,用汇编语法解释就是:

pop IP                          ;把栈顶元素值赋值给IP,把栈顶向下移动两字节

pop CS                         ;把新栈顶元素复制给CS,再次将栈顶向下移动两字节

CPU在执行call指令时,进行两步操作,(1)将当前的IP或CS与IP压入栈中,(2)jmp标号处

call实现转移的方法和jmp原理相同,call分为两种(不含短转移,因为call操作需要用到栈,而对栈的操作是默认16位的),近转移,远转移。

call  标号                       ;相当于执行push  IP,jmp near prt 标号

call far prt 标号             ;相当于执行push CS,push IP,jmp far prt 标号

体会一下call和ret指令利用栈的理由,在思考一下C语言中的递归算法,是不是能深刻了解递归中函数的返回过程了?不断call函数,然后就把IP不断压入栈中,最后返回时,不断popIP,就完成了逐级返回。

2.寄存器冲突

在这之前,已经提到过寄存器冲突的问题了(CX的循环问题),现在介绍的是一种标准的调用函数的过程。

因为我们CPU中的寄存器是有限的,所以你的子函数也难免会利用到你父函数中使用的寄存器,那么为了解决这类问题,汇编语言在编写子函数一般使用以下框架:

(1)子程序开始:将父程序的所有寄存器入栈。

(2)子程序内容

(3)子程序结束:将寄存器出栈恢复

(4)ret,retf返回

因为利用到了栈,所以子程序中改变的寄存器的值并不会影响到父程序(除非你在子程序中直接修改栈中内容),这也就更加深刻的解释了C语言中传参的问题,为什么实参无法影响到形参。

日后如果碰到汇编程序一开头就在不断push一些寄存器,那么这接下来的程序就很可能是子函数了。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • 8086汇编 本笔记是笔者观看小甲鱼老师(鱼C论坛)《零基础入门学习汇编语言》系列视频的笔记,在此感谢他和像他一样...
    Gibbs基阅读 37,796评论 8 114
  • 王爽汇编全书知识点大纲 第一章 基础知识 机器语言 汇编语言的产生 汇编语言的组成 存储器 cpu对存储器的读写 ...
    2c3ba901516f阅读 7,328评论 0 1
  • 计算机通过执行指令序列来使机器得以工作,所以对于每一系列的计算机都有指定的一组指令集供计算机使用,这组指令...
    未来科技工作室阅读 12,540评论 1 10
  • 汇编总结 汇编的发展史 机械语言 由0和1组成的机器指令(如:0101 0001 1101 0110) 汇编语言(...
    iChuck阅读 5,123评论 1 8
  • 下去寄快递,同事说帮忙带一下,一看,份量不轻呀,想拒绝,话到嘴边说不出口。 这种“拒你在心口难开,还要委屈”的场景...
    豆子121阅读 1,778评论 8 4

友情链接更多精彩内容