当前位置:   article > 正文

汇编语言流程转移与子程序篇--05_汇编远转移

汇编远转移

汇编语言流程转移与子程序篇--05


本系列文章参考汇编语言第四版和汇编语言程序设计 贺利坚主讲整理而成


“转移”综述

在这里插入图片描述


操作符offset

用操作符offset取得标号的偏移地址

在这里插入图片描述


练习

在这里插入图片描述


jmp指令

jmp指令——无条件转移

jmp指令的功能 : 无条件转移,可以只修改IP,也可以同时修改CS和IP

jmp指令要给出两种信息:

  • 转移的目的地址
  • 转移的距离

  • 段间转移(远转移): jmp 2000:1000
  • 段内短转移: jmp short 标号 ; IP的修改范围为 -128~127,8位的位移
  • 段内近转移: jmp near ptr 标号 ; IP的修改范围为 -32768~32767,16位的位移

jmp指令:依据位移进行转移

在这里插入图片描述

076A:0003 EB03 JMP 0008
076A:0005 050100 ADD AX,0001
076A:0008 40 INC AX
  • 1
  • 2
  • 3
  • 当JMP指令被读入指令缓冲器后,IP=IP+所读取的指令长度=0005
  • CPU执行指令缓冲器中的指令EB03
  • IP=IP+3=0005+0003=0008

JMP short s : 对应的机器指令中,包含的是当前指令下一条指令开始位置处,到段内目标地址的位移


两种段内转移

在这里插入图片描述


远转移:jmp far ptr 标号

在这里插入图片描述
远转移(跨段转移)中,转移机器指令中包含的是目标地址,而不是相对位移


转移地址在寄存器中的jmp指令

在这里插入图片描述


转移地址在内存中的jmp指令

在这里插入图片描述


jmp指令小结

在这里插入图片描述


其他转移指令

jcxz指令

在这里插入图片描述


loop指令

在这里插入图片描述


根据位移进行“相对”转移的意义

在这里插入图片描述


call指令和ret指令

模块化程序设计

在这里插入图片描述


call 指令

在这里插入图片描述

将当前IP或CS和IP压栈,是为了子程序调用结束后,程序能够回到原来的位置,继续往下面执行


指令“call far ptr 标号”实现的是段间转移

在这里插入图片描述


转移地址在寄存器中的call指令

在这里插入图片描述


转移地址在内存中的call指令

在这里插入图片描述


返回指令:ret 和 retf

在这里插入图片描述

设计用来回到子程序调用结束后,源程序继续运行的地址处


call 和 ret 的配合使用

具有子程序的源程序的框架

在这里插入图片描述


call 和 ret 的配合使用

在这里插入图片描述
注意观察在调用call指令和ret指令时,sp栈顶寄存器值的变化

call需要使用栈,但是这里程序没有分配栈空间,是默认给出的栈空间,因此这是非常危险的,鬼知道默认的空间,是不是在别的啥子地方被占用了


例:为call和ret指令设置栈

在这里插入图片描述


乘法:mul 指令

回顾:除法div 指令

在这里插入图片描述


用 mul 指令做乘法

在这里插入图片描述


应用实例

在这里插入图片描述


汇编语言的模块化程序设计

模块化程序设计

在这里插入图片描述


参数和结果传递的问题

在这里插入图片描述


用寄存器来存储参数和结果是最常使用的方法

在这里插入图片描述


用内存单元批量传递数据

在这里插入图片描述


用栈传递参数

在这里插入图片描述
保存BP寄存器旧值的原因,在于子程序中需要使用到BP寄存器,而BP寄存器可能在主程序或者其他程序中被使用中,因此当前子程序用完BP寄存器后,需要恢复其旧值才可以。

ret 4是先恢复IP寄存器原先值,然后再讲SP栈顶地址寄存器的偏移值+4,这里是跳过a和b两个数据,因为这两个值没用了,不需要继续占据着栈空间


程序的执行过程中栈的变化

在这里插入图片描述


小结:参数和结果传递的问题

问题:根据提供的N,计算N的3次方。

考虑

  • (1)我们将参数N存储在什么地方?
  • (2)计算得到的数值,存储在什么地方?

方案:

  • 用寄存器传递参数
  • 用内存单元进行参数传递
  • 用栈传递参数

寄存器冲突问题

引子

在这里插入图片描述
之前我们每次循环时,都是提前将要循环的次数保存在了cx寄存器中,但是有没有办法不提前写好循环次数,而在合适的时机结束循环呢?

  • 在处理字符串问题时,可以模仿c语言的\0结束符号

代码:编程将data段中的字符串转化为大写

在这里插入图片描述
cx寄存器使用的冲突,会导致程序运行的奔溃,这是个大问题,怎么解决呢?


寄存器冲突问题的解决

在这里插入图片描述


寄存器冲突问题的解决示例

在这里插入图片描述


标志寄存器

在这里插入图片描述


认识标志寄存器的特殊之处

在这里插入图片描述


ZF-零标志(Zero Flag)

在这里插入图片描述


PF-奇偶标志(Parity Flag)

在这里插入图片描述


SF-符号标志(Sign Flag)

在这里插入图片描述


CF-进位标志(Carry Flag)

在这里插入图片描述


OF-溢出标志(Overflow Flag)

在这里插入图片描述


带进(借)位的加减法

adc-带进位加法指令

在这里插入图片描述

对于最后一种因为减法产生借位而导致CF=1的情况,显然不是我们期望的样子,因此是存在问题的,但是这种问题的解决需要程序员自己去控制


adc指令应用:大数相加

在这里插入图片描述


128位数据的相加

在这里插入图片描述

  • sub ax,ax不可以替换为mov ax,0 ,因为sub ax,ax算出来ax=0后,因为没有产生借位,因此CF=0,确保能够清空CF之前的状态,确保不会影响下面的adc操作
  • inc di不会影响进位标志位CF,但是add di 2会影响CF标记位,如果发生溢出了,CF会被设置为1

sbb指令

在这里插入图片描述

  • 低十六位相减,如果产生了借位,那么高16位就需要处理低十六位产生的借位

cmp与条件转移指令

cmp指令

在这里插入图片描述


无符号数比较与标志位取值

在这里插入图片描述


有符号数比较与标志位取值

在这里插入图片描述


条件转移指令

在这里插入图片描述


条件转移指令的使用

在这里插入图片描述


条件转移指令应用

在这里插入图片描述


应用示例

在这里插入图片描述


在这里插入图片描述


在这里插入图片描述


DF标志和串传送指令

问题的提出

在这里插入图片描述


DF标志和串传送指令

在这里插入图片描述


rep指令

在这里插入图片描述


应用实例

在这里插入图片描述

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/繁依Fanyi0/article/detail/486916
推荐阅读
相关标签
  

闽ICP备14008679号