1. 程式人生 > >組合語言(第3版) 第11章相關內容及實驗11

組合語言(第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


結果:

在這裡插入圖片描述