标志寄存器05 – 零基础入门学习汇编语言58

第十一章:标志寄存器05

让编程改变世界

Change the world by program

编程训练

编程实现如下功能:如果(ah)=(bh)则(ah)=(ah)+(ah),否则(ah)=(ah)+(bh)。

cmp ah,bh

je s

add ah,bh

jmp short ok

s:      add ah,ah

ok:   ret

检测比较结果的条件转移指令

虽然 je 的逻辑含义是“相等则转移”,但它进行的操作是,ZF=1时则转移。

“相等则转移”这种逻辑含义,是通过和 cmp 指令配合使用来体现的,因为是cmp 指令为“ZF=1”赋予了“两数相等”的含义。

至于究竟在je之前使不使用cmp指令,在于我们的安排。

je检测的是ZF位置,不管je 前面是什么指令,只要CPU执行je指令时,ZF=1,那么就会发生转移。

比如:

mov ax,0

add ax,0

je s

inc ax

s:      inc ax

执行后,(ax)=1。add ax,0 使得ZF=1,所以je指令将进行转移。

可在这个时候发生的转移确不带有“相等则转移”的含义。因为此处的je指令检测到的ZF=1 ,不是由cmp等比较指令设置的,而是由add指令设置的,并不具有“两数相等”的含义。

但无论“ZF=1” 的含义如何,是什么指令设置的,只要是ZF=1,就可以使得je指令发生转移。

CPU提供了cmp指令,也提供了 je 等条件转移指令,如果将它们配合使用,可以实现根据比较结果进行转移的功能。

但这只是“如果”,只是一种合理的建议,和事实上常用的方法。

但究竟是否配合使用它们,完全是你自己的事情。这就好像,call和ret指令的关系一样。

对于jne、jb、jnb、ja、jna等指令和cmp指令配合使用的思想和je相同,可以自己分析一下。

课堂练习

我们来看一组程序:

data段中的8个字节如下:

data segment

db 8,11,8,1,8,5,63,38

data ends

(一)编程:统计data段中数值为8的字节的个数,用ax保存统计结果。

编程思路:初始设置(ax)=0,然后用循环依次比较每个字节的值,找到一个和8相等的数就将ax的值加1。

源码分析:相关代码下载

第二种方案:相关代码下载

比起第一个程序,它直接的遵循了“等于8则计数值加1”的原则,用je指令检测等于8的情况,但是没有第一个程序精简。

第一个程序用 jne 检测不等于 8 的情况 ,从而间接地检测等于 8 的情况。

要注意在使用 cmp 和条件转移指令时的这种编程思想。

(二)编程:统计data段中数值大于8的字节的个数,用ax保存统计结果。

编程思路:初始设置(ax)=0,然后用循环依次比较每个字节的值,找到一个大于8的数就将ax的值加1。

源码分析:相关代码下载

(三)编程:统计data段中数值小于8的字节的个数,用ax保存统计结果。

编程思路:初始设置(ax)=0,然后用循环依次比较每个字节的值,找到一个小于8的数就将ax的值加1。

源码分析:相关代码下载

上面讲解了根据无符号数的比较结果进行转移的条件转移指令。

根据有符号数的比较结果进行转移的条件转移指令的工作原理和无符号的相同,只是检测了不同的标志位。

我们在这里主要探讨的是cmp、标志寄存器的相关位、条件转移指令三者配合应用的原理,这个原理具有普遍性,而不是逐条讲解条件转移指令。

DF标志和串传送指令

flag的第10位是DF,方向标志位。

在串处理指令中,控制每次操作后si,di的增减。

DF = 0:每次操作后si,di递增

DF = 1:每次操作后si,di递减

格式1: movsb

功能:(以字节为单位传送)

(1)

((es)×16 + (di)) = ((ds) ×16 + (si))

(2)

如果DF = 0则:(si) = (si) + 1 (di) = (di) + 1

如果DF = 1则:(si) = (si) – 1 (di) = (di) – 1

movsb 的功能是将 ds:si 指向的内存单元中的字节送入 es:di中,然后根据标志寄存器DF位的值,将 si和di递增或递减。

当然,也可以传送一个字: movsw

格式2:movsw

功能:(以字为单位传送)将 ds:si 指向的内存字单元中 word 送入 es:di 中,然后根据标志寄存器DF位的值,将si和di递增2或递减2。

movsb和movsw进行的是串传送操作中的一个步骤,一般来说,movsb 和 movsw 都和rep配合使用。

格式如下:rep movsb

rep的作用是根据cx的值,重复执行后面的串传送指令。

由于每执行一次movsb指令si和di都会递增或递减指向后一个单元或前个单元,则rep movsb就可以循环实现(cx)个字符的传送。

由于flag的DF位决定着串传送指令执行后,si和di改变的方向,所以CPU应该提供相应的指令来对DF位进行设置,从而使程序员能够决定传送的方向。

8086CPU提供下而两条指令对DF位进行设置:

cld指令:将标志寄存器的DF位置0

std指令:将标志寄存器的DF位置1

视频下载
技术, IT技术, 汇编语言, 视频教程



                                                    风险提示及免责条款

市场有风险,投资需谨慎。本文不构成个人投资建议,也未考虑到个别用户特殊的投资目标、财务状况或需要。用户应考虑本文中的任何意见、观点或结论是否符合其特定状况。据此投资,责任自负。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部