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

Posted 大忽悠爱忽悠

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了汇编语言流程转移与子程序篇--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
  • 当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指令


应用实例

以上是关于汇编语言流程转移与子程序篇--05的主要内容,如果未能解决你的问题,请参考以下文章

汇编语言-其他转移指令CALL

8086汇编 jcxz 指令

2017.10.18 汇编语言语法和DOS功能调用

汇编语言基础学习以及各种指令记忆(实验八)

jmp指令用法

关于汇编的段内转移