汇编语言(第3版) 第11章相关内容及实验11

第十一章 标志寄存器

章节内容

概述

主要介绍了标志寄存器和其中的CF,PF,ZF,SF,OF,DF标志位。

标志寄存器的作用:

  1. 用来储存相关指令的某些执行结果
  2. 用来为CPU执行相关指令提供行为依据
  3. 用来控制CPU的相关工作方式

8086CPU 的 flag 寄存器结构:

在这里插入图片描述

8086CPU指令集中:add、sub、mul、div、inc、or、and等(大多为运算指令)指令执行会影响标志寄存器。

像 mov、push、pop等(大多是传送指令)指令执行不影响标志寄存器。

本章还介绍了与标志寄存器有关的adc、sbb、cmp、movsb、movsw、pushf、popf等指令。

ZF标志

flag的第6位,零标志位,若相关指令执行后结果为0,则zf=1,否则zf=0;

PF标志

flag的第2位,奇偶标志,若相关指令执行后结果中所有bit位中1的个数为偶数,则pf=1,否则pf=0;

SF标志

flag的第7位,符号标志位,若相关指令执行后结果为负,则sf=1,否则sf=0;

CF标志

flag的第0位,进位标志位,在进行无符号数运算时,记录运算结果的最高有效位向更高位的进位值,或从更高位的借位值,进位/借位了cf=1,否则cf=0;

OF标志

flag的第11位,溢出标志位,在进行有符号数运算时,记录运算结果是否发生了溢出,溢出了of=1,否则of=0;

(如进行8位寄存器或内存单元有符号运算,超过范围-128~127为溢出,16位有符号运算,超过范围-32768~32767为溢出)

CF和OF所表示的进位和溢出,分别是对无符号数和有符号数运算而言的,他们之间没有任何关系。

DF标志

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

df=0,每次操作后si、di递增。

df=1,每次操作后si、di递减。

cld指令设置df=0

std指令设置df=1

串传送指令会在后文介绍。

adc/sbb指令

带进位加法/带借位减法指令,利用了CF位上记录的进位/借位值。

指令格式: adc 操作对象 1,操作对象 2

功能: 操作对象 1 = 操作对象 1 + 操作对象 2 + CF

指令格式: sbb 操作对象 1,操作对象 2

功能: 操作对象 1 = 操作对象 1 - 操作对象 2 - CF

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

cmp是比较指令,相当于不保存结果的减法,但是会对标志寄存器产生影响,其他若干指令通过识别被影响的寄存器位得知比较结果。

指令格式: cmp 操作对象 1,操作对象 2

功能: 计算操作对象 1 - 操作对象 2 但不保存结果,根据计算结果对标志寄存器进行设置

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

指令 字母表示意义 含义 检测的相关标志位
je jump equal 等于则转移 zf=1
jne jump not equal 不等于则转移 zf=0
jb jump below 低于则转移 cf=1
jnb jump not below 不低于则转移 cf=0
ja jump above 高于则转移 cf=0 且 zf=0
jna jump not above 不高于则转移 cf=1 或 zf=1

这些常与cmp配合使用。

注意,对于有符号数和无符号数,这些指令检测的标志位可能会不同,但这里不做详细探究。(指令的重点不在这)

串传送指令

movsb

执行相当于以下几步骤

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

根据df标志位的值递增/递减1

movsw

与movsb类似,但每次传送一个字

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

根据df标志位的值递增/递减2

movsb/movsw常与rep配合使用构成一个串传送操作。

格式为rep movsb / rep movsw

rep根据cx的值,重复执行若干次之后的串传送指令。

相当于汇编语言下的

s:	movsb
	loop s
;以及
s:	movsw
	loops

从而实现(cx)个字符或字的传送,由df标志位控制方向(递增或递减)

pushf和popf指令

pushf将标志寄存器的值压栈,popf将栈中的值弹出送入标志寄存器中。

标志寄存器在Debug中的表示

Debug中标志寄存器的各个位是单独表示的。

如图:

在这里插入图片描述

各标志位的表示:

标志 值为1的标记 值为0的标记
of OV NV
sf NG PL
zf ZR NZ
pf PE PO
cf CY NC
df DN UP

实验11 编写子程序

编写子程序,将包含任意字符,以0结尾的字符串中的小写字母转变成大写字母。

名称:letterc

功能:将以0结尾的字符串中的小写字母转变成大写字母

参数:ds:si指向字符串首地址。

需要用到本章学习的cmp和条件转移指令判断一个字符是否为小写字母,其他就挺简单了。

代码如下:

assume cs:codesg
datasg segment
        db "Beginner's All-purpose Symbolie Instruction Code.",0
datasg ends
stacksg segment
        db 16 dup (0)
stacksg ends
codesg segment
        begin :
                mov ax,datasg
                mov ds,ax
                mov si,0
                mov ax,stacksg
                mov ss,ax
                mov sp,16
                call letterc

                mov ax,4c00h
                int 21h
        letterc:
                ;寄存器入栈
                push si
                push cx
                mov ch,0
                ;子程序
                letterc_begin:
                mov cl,[si]
                jcxz betterc_ok
                cmp cl,'a'
                jb letterc_next
                cmp cl,'z'
                ja letterc_next
                and cl,11011111b
                mov [si],cl
                letterc_next:
                inc si
                jmp short letterc_begin

                betterc_ok:
                ;寄存器出栈
                pop cx
                pop si
        ret

        codesg ends
end begin


结果:

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/weixin_42279809/article/details/83959896
今日推荐