第11章知识点及检测点实验11答案

第11章 标志寄存器

目前我们知道的寄存器有:ax,bx,cx,dx,si,di,ip,sp,bp,cs,ss,ds,es这13个寄存器了,而本章我们要学习的便是第14个寄存器也就是最后一共寄存器–flag寄存器
flag寄存器和前面的寄存器都不一样,它是按位存放数据,且每一位都有特定的含义

flag寄存器的结构:
在这里插入图片描述

11.1~11.5

这这里一共给我们介绍了ZF,PF,SF,CF,OF标志,总结来说就是:

标志位   名称      范围      特点
ZF    零标志位             结果为0则ZF=1,反之ZF=0
PF    奇偶标志位           结果的二进制位中1的个数为偶数则PF为1,反之为0
SF    符号标志位  有符号数  结果为0则SF=1,反之SF=0
CF    进位标志位  无符号数  运算过程中有进位或借位则CF=1,反之为0
OF    溢出标志位  有符号数  结果溢出的话则OF=1,反之为0

检测点11.1

sub al,al            1  1  0
mov al,1             1  1  0
push ax              1  1  0
pop bx               1  1  0
add al,bl            0  0  0
add al,10            0  1  0
mul al               0  1  0

注意:mov,push,pop等指令不会改变标志寄存器各位的值!

检测点11.2

                    CF    OF    SF    ZF    PF    
sub al,al           0     0      0     1     1         
mov al,10h          0     0      0     1     1          
add al,90h          0     0      1     0     1         
mov al,80h          0     0      1     0     1         
add al,80h          1     1      0     1     1          
mov al,0FCh         1     1      0     1     1          
add al,05h          1     0      0     0     0         
mov al,7DH          1     0      0     0     0         
add al,0Bh          0     1      1     0     1           

11.6 adc指令

adc指令和CF有联系:
adc ax,bx --> (ax) = (ax) + (bx) + CF

当上一步的运算结果有进位的时候CF=1,而我们可以利用这个指令实现对更大的数据进行加法运算

add ax,bx

上面的式子等价于下面的

add al,bl
adc ah,bh

大概就是这样,进位之后CF会存储,然后进行更高位运算的时候加上
回答一下p221的问题,能不能用add指令代替4个in指令:
不能,因为程序中用到了CF,使用add指令进行运算会导致CF的值发生变化!(重置为0)

11.7 sbb指令

sbb指令和adc指令很像,不过sbb指令利用的是CF上的借位
sbb ax,bx --> (ax) = (ax) - (bx) - CF

如计算003E1000H-00202000H等同于:

mov bx,1000H
mov ax,003EH
sub bx,2000H
sbb ax,0020H

11.8 cmp指令

cmp指令本质上是进行减法运算,并将结果的正负存储在标志寄存器中,但所得结果不会存储
cmp指令的作用便是比较两个数的大小,例如

jmp ax,bx

执行后ZF=1,说明结果为0,即ax=ax-bx=0,说明ax=bx
对于无符号数,看zf,cf,有符号数看sf,of,zf

我们目前学习cmp指令主要会和下面一些条件转移指令搭配:

je jne jb jnb ja jna

j-->jump
e-->equal
n-->not
a-->above
b-->below

cmp指令和je,ja等条件转移指令一起使用的时候,其实不必每个都去计算标志寄存器的值来判断运算数之间大小(这是计算机的判断方法),我们只需要当成C语言的if语句一样使用就可以了!

检测点11.3

mov ax,0f000h
mov ds,ax

mov bx,0
mov dx,0
mov cx,32

s:
  mov al,[bx]
  cmp al,32
  jb s0
  cmp al,128
  ja s0
  inc dx

s0:
  inc bx
  loop s  
mov ax,0f000h
mov dx,ax

mov bx,0
mov dx,0
mov cx,32
s:
  mov al,[bx]
  cmp al,32
  jna s0
  cmp al,128
  jnb s0
  inc dx

s0:
  inc bx
  loop s

11.10 DF标志和串传送指令

DF    方向标志位 
df=1则si,di递减,df=0则si,di递增

串传送指令:

movsb指令 ,执行后进行以下步骤:
1.mov es:[di],ds:[si]
2.通过DF值来对si和di递增递减

movsb每次复制的是一共byte字节,还有movsw指令,每次复制一个word字

使用串传送指令时会和rep搭配:

rep movsb执行后等同于:
s:movsb
  loop s
可以看出loop指令参与运算,说明cx的值决定了rep movsb指令复制的次数

我们前面说到df=1则si和di递减,df=0则si和di递增。那df的值我们该如何控制呢?

cld      df位置0
std      df位置1

我们举一个简单的例子:

data segment
	db 'welcome to masm!'
	db 16 dup (0)
data ends

codesg segment
	mov ax,data
	mov ds,ax
	mov si,0
	mov es,ax
	mov di,16
	mov cx,16
	cld           ;执行cld指令df置0,下一条指令执行时si和di将递增,正向传送
	rep movsb
codesg ends

11.11 pushf和popf

push和pop指令将数据压入栈中或出栈,而pushf和popf指令专门用于标志寄存器中的数据出入栈,让我们一起看看检测点11.4

检测点11.4
在这里插入图片描述

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

实验11

在此附上我写的答案:

codesg segment
begin:mov ax,datasg
   	mov ds,ax
   	mov si,0
   	call letterc

	mov ax,4c00h
	int 21h

letterc:
	cmp ds:[si],61H    ;和a作比较
	jb ok          ;如果小于61则直接跳到标号ok处
	cmp ds:[si],86H  ;和z作比较
	ja ok   ;大于86则直接跳到ok处
	and ds:[si],11011111B   ;到这一步的都是大于等于61且小于等于86H的字符
	              ;也就是a~z
ok: mov cx,ds,[si]   ;如果是0,赋给cx,执行jcxz指令将会跳到标号s处直接结束程序
	jcxz s
	inc si
	jmp short letterc   ;开始处理下一个字符

s:	ret
codesg ends
end begin
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值