我是靠谱客的博主 拉长路灯,最近开发中收集的这篇文章主要介绍汇编语言(王爽版)学习笔记 第十一章 标志寄存器(2),觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

文章目录

    • 11.8 cmp指令
    • 11.9 检测比较结果的条件转移指令
      • 检测点11.3
    • 11.10 DF标志和串传送指令
    • 11.11 pushf和popf
      • 检测点11.4
    • 11.12 标志寄存器在Debug中的表示

11.8 cmp指令

cmp是比较指令,cmp的功能相当于减法指令,只是不保存结果。cmp指令执行后,将对标志寄存器产生影响。其他相关指令通过识别这些被影响的标志寄存器位来得知比较结果。

cmp 指令格式:cmp 操作对象1,操作对象2
功能:计算操作对象1-操作对象2,但并不保存结果,仅仅根据计算结果对标志寄存器进行设置。
比如,指令 cmp ax,ax 
做(ax)-(ax)的运算,结果为0,但并不在ax中保存,仅影响flag的相关各位。指令执行后,zf=1,pf=1,sf=0,cf=0,of=0
下面的指令:
mov ax,8
mov bx,3
cmp ax,bx
执行后,(ax)=8,zf=0,pf=1,sf=0,cf=0,of=0

其实,我们通过cmp指令执行后,相关标志位的值就可以看出比较的结果。

cmp ax,bx

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

sf的值不能判断大小的关键原因在于发生了溢出。如果没有溢出发生的话,那么,实际结果的正负和逻辑上真正结果的正负就一致了。

所以,我们应该再考查sf(得知实际结果的正负)的同时考查of(得知有没有溢出),就可以得知逻辑上真正结果的正负,同时就可以知道比较的结果。

以cmp ah,bh为例讲解:
在这里插入图片描述


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

“转移”指的是它能够修改IP,而“条件”指的是它可以根据某种条件,决定是否修改IP。

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

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

cmp ah,bh
je s
add ah,bh
jmp short ok
	s:add ah,ah
ok:...

在这里插入图片描述
在这里插入图片描述
我们来看下面的一组程序。
data段中的8个字节如下:

data segment
	db 8,11,8,1,8,5,63,38
data ends

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

在这里插入图片描述
在这里插入图片描述

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

在这里插入图片描述

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

在这里插入图片描述

检测点11.3

(1)补全下面的程序,统计F000:0处32个字节中,大小在[32,128]的数据的个数。
在这里插入图片描述
分析: 此处用dx保存大小在[32,128]的数据的个数。低于32跳转到s0处进行下一次循环,高于128也跳转到s0处进行下一次循环。

(2)补全下面的程序,统计F000:0处32个字节中,大小在(32,128)的数据的个数。
在这里插入图片描述

注:

cmp ah,bh
跳转指令(以ja s0举例)
"ja s0"表示:ah的值高于bh的值,则跳转!
注意是前者比后者高(或低,或不高于,或不低于)

11.10 DF标志和串传送指令

flag的第10位是DF,方向标志位。在串处理指令中,控制每次操作后的si、di的增减。

df=0		每次操作后si、di递增;
df=1 	每次操作后si、di递减。

我们来看下面的一个串传送指令。

格式:movsb
功能:执行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"表示传送一个byte型的数据。

在这里插入图片描述

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

rep movsb
用汇编语法来描述 rep movsb 的功能就是:
s:movsb
	loop s
可见,rep的作用是根据cx的值,重复执行后面的串传送指令。
由于每执行一次movsb指令si和di都会递增或递减指向后一个单元或前一个单元,则rep movsb就可以循环实现(cx)个字符的传送。
rep movsw
相当于:
s:movsw
	loop s

在这里插入图片描述

(1)编程,用串传送指令,将data段中的第一个字符串复制到它后面的空间中。

在这里插入图片描述

mov ax,data
mov ds,ax
mov si,0		;ds:si指向data:0
mov es,ax
mov di,16		;es:di指向data:0010
mov cx,16;		;(cx)=16,rep循环16次
cld
rep movsb

(2)编程,用串传送指令,将F000H段中最后的16个字符复制到data段中。

在这里插入图片描述


11.11 pushf和popf

pushf的功能是将标志寄存器的值压栈,而popf是从栈中弹出数据,送入标志寄存器中。
pushf和popf,为直接访问标志寄存器提供了一种方法。

检测点11.4

下面的程序执行后:(ax)=?

mov ax,0		;ax=0000
push ax			;ax=0000
popf			;ax=0000,把标志寄存器的各位置为0
mov ax,0fff0h	;ax=0fff0h
add ax,0010h	;ax=0fff0h+0010h=(0000)h
pushf
pop ax		
and al,11000101B
and ah,00001000B

这个要翻一下本章最开始的flag寄存器示意图。
在这里插入图片描述

0fff0h+0010h=10000h;因为产生了进位,1是进位值,ax中只能保存0000h
假设进行无符号数运算:
0fff0h+0010h=10000h,产生了进位。
假设进行有符号数运算:
-10h+10h=0,没有产生溢出。
flag各位结果如下:
CF=1,无符号数运算产生了进位;
PF=1,奇偶标志位ax=0000 0000h,偶数个1;
AF=1;辅助进位标志位。运算过程中看最后四位,不论长度为多少。最后四位向前有进位或者借位,AF=1,否则AF=0;后面4位产生了进位,AF=1;
ZF=1,ax=0000,结果为0;
SF=0,符号标志位,ax结果非负;
TF=0;调试标志位。当TF=1时,处理器每次只执行一条指令,即单步执行;TF在popf的时候被置为0;
IF=0;中断允许标志位。它用来控制8086是否允许接收外部中断请求。若IF=1,8086能响应外部中断,反之则屏蔽外部中断;IF在popf的时候被置为0;
DF=0;方向标志位。在串处理指令中,每次操作后,如果DF=0,si、di递增,如果DF=1,si、di递减;注意此处DF的值是由程序员进行设定的 cld命令是将DF设置为0,std命令是将DF设置为1;DF在popf的时候被置为0;
OF=0;溢出标志位,没有溢出;
标志寄存器的其他位在popf的时候被置为0;

flag各位如下:
在这里插入图片描述

pop ax之后
ah=0000 0000;al=0101 0101
and al,11000101B的结果为 (al)=0100 0101B
and ah,00001000B的结果为(ah)=0000 0000B
ax=0000 0000 0100 0101=69=45h

故程序执行之后,(ax)=45h.


11.12 标志寄存器在Debug中的表示

在这里插入图片描述

最后

以上就是拉长路灯为你收集整理的汇编语言(王爽版)学习笔记 第十一章 标志寄存器(2)的全部内容,希望文章能够帮你解决汇编语言(王爽版)学习笔记 第十一章 标志寄存器(2)所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(58)

评论列表共有 0 条评论

立即
投稿
返回
顶部