1. 程式人生 > >組合語言--微機CPU的指令系統(五)(算術運算指令)

組合語言--微機CPU的指令系統(五)(算術運算指令)

(3)算術運算指令

算術運算指令是反映CPU計算能力的一組指令,也是程式設計時經常使用的一組指令。它包括:加、減、乘、除及其相關的輔助指令。

該組指令的運算元可以是8位、16位和32位(80386+)。當儲存單元是該類指令的運算元時,該運算元的定址方式可以是任意一種儲存單元定址方式。

1、加法指令 

(a)加法指令ADD(ADD Binary Numbers Instruction)

指令的格式:ADD Reg/Mem, Reg/Mem/Imm

受影響的標誌位:AF、CF、OF、PF、SF和ZF

指令的功能是把源運算元的值加到目的運算元中。

(b)帶進位加指令ADC(ADD With Carry Instruction)

指令的格式:ADC Reg/Mem, Reg/Mem/Imm

受影響的標誌位:AF、CF、OF、PF、SF和ZF

指令的功能是把源運算元和進位標誌位CF的值(0/1)一起加到目的運算元中。

(c)加1指令INC(Increment by 1 Instruction)

指令的格式:INC Reg/Mem

受影響的標誌位:AF、OF、PF、SF和ZF,不影響CF

指令的功能是把運算元的值加1。

(d)交換加指令XADD(Exchange and Add)

指令的格式:XADD Reg/Mem, Reg ;80486+

受影響的標誌位:AF、CF、OF、PF、SF和ZF

指令的功能是先交換兩個運算元的值,再進行算術“加”法操作。

例5.3 已知有二個32位數d1和d2(用資料型別DD說明),編寫程式片段把d2的值加到d1中。

解:32位數d1和d2在記憶體中如下所示。

clip_image002[4]

方法1:用16位暫存器編寫程式

MOV AX, word ptr d1 ;由於d1是雙字型別,必須使用強制型別說明符。以下同。

MOV DX, word ptr d1+2 ;(DX,AX)構成一個32位資料

ADD AX, word ptr d2 ;低字相加

ADC DX, word ptr d2+2 ;高字相加。在低字相加時,有可能會產生“進位”

MOV word ptr d1, AX ;低字送給d1的低字

MOV word ptr d1+2, DX ;高字送給d1的高字

方法2:用32位暫存器編寫程式

MOV EAX, d1

ADD EAX, d2

MOV d1, EAX

從上面兩段程式不難看出:用32位暫存器來處理32位資料顯得簡單、明瞭,而16位微機雖然也能處理32位資料,但做起來就要複雜一些。

2、減法指令

(a)減法指令SUB(Subtract Binary Values Instruction)

指令的格式:SUB Reg/Mem, Reg/Mem/Imm

受影響的標誌位:AF、CF、OF、PF、SF和ZF

指令的功能是從目的運算元中減去源運算元。(前面減去後面)

(b)帶借位減SBB(Subtract with Borrow Instruction)

指令的格式:SBB Reg/Mem, Reg/Mem/Imm

受影響的標誌位:AF、CF、OF、PF、SF和ZF

指令的功能是把源運算元和標誌位CF的值從目的運算元中一起減去。

(c)減1指令DEC(Decrement by 1 Instruction)

指令的格式:DEC Reg/Mem

受影響的標誌位:AF、OF、PF、SF和ZF,不影響CF

指令的功能是把運算元的值減去1。

(d)求補指令NEG(Negate Instruction)

指令的格式:NEG Reg/Mem

受影響的標誌位:AF、CF、OF、PF、SF和ZF

指令的功能:運算元=0-運算元,即改變運算元的正負號。

例5.4 已知有二個32位數d1和d2,編寫程式片段從d1中減去d2的值。

解:

方法1:用16位暫存器編寫程式

MOV AX, word ptr d1 ;取低字

MOV DX, word ptr d1+2 ;取高字,(DX,AX)構成一個32位資料

SUB AX, word ptr d2 ;低字相減

SBB DX, word ptr d2+2 ;高字相減。在低字相減時,有可能會產生“借位”

MOV word ptr d1, AX ;低字送給d1的低字

MOV word ptr d1+2, DX ;高字送給d1的高字

方法2:用32位暫存器編寫程式

MOV EAX, d1

SUB EAX, d2

MOV d1, EAX

3、乘法指令

計算機的乘法指令分為無符號乘法指令和有符號乘法指令,它們的唯一區別就在於:資料的最高位是作為“數值”參與運算,還是作為“符號位”參與運算。

乘法指令的被乘數都是隱含運算元,乘數在指令中顯式地寫出來。CPU會根據乘數是8位、16位,還是32位運算元,來自動選用被乘數:AL、AX或EAX。

指令的功能是把顯式運算元和隱含運算元相乘,並把乘積存入相應的暫存器中。

(a) 無符號數乘法指令MUL(Unsigned Multiply Instruction)

指令的格式:MUL Reg/Mem

受影響的標誌位:CF和OF(AF、PF、SF和ZF無定義)

指令的功能是把顯式運算元和隱含運算元(都作為無符號數)相乘,所得的乘積按表5.2的對應關係存放。

clip_image004[4]

(b) 有符號數乘法指令IMUL(Signed Integer Multiply Instruction)

指令的格式: IMUL Reg/Mem

IMUL Reg, Imm ;80286+

IMUL Reg, Reg, Imm ;80286+

IMUL Reg, Reg/Mem ;80386+

受影響的標誌位:CF和OF(AF、PF、SF和ZF無定義)

1)指令格式1——該指令的功能是把顯式運算元和隱含運算元相乘,所得的乘積按表5.2的對應關係存放。

2)指令格式2——其暫存器必須是16位/32位通用暫存器,其計算方式為:

Reg ← Reg × Imm

3)指令格式3——其暫存器只能是16位通用暫存器,其計算方式為:

Reg1 ← Reg2×Imm 或 Reg1 ← Mem×Imm

4)指令格式4——其暫存器必須是16位/32位通用暫存器,其計算方式為:

Reg1 ← Reg1×Reg2 或 Reg1 ← Reg1×Mem

在指令格式2~4中,各運算元的位數要一致。如果乘積超過目標暫存器所能儲存的範圍,則系統將置溢位標誌OF為1。

4、除法指令

除法指令的被除數是隱含運算元,除數在指令中顯式地寫出來。CPU會根據除數是8位、16位,還是32位,來自動選用被除數AX、DX-AX,還是EDX-EAX。

除法指令功能是用顯式運算元去除隱含運算元,可得到商和餘數。當除數為0,或商超出資料型別所能表示的範圍時,系統會自動產生0號中斷。

(a) 無符號數除法指令DIV(Unsigned Divide Instruction)

指令的格式:DIV Reg/Mem

指令的功能是用顯式運算元去除隱含運算元(都作為無符號數),所得商和餘數按表5.3的對應關係存放。指令對標誌位的影響無定義。

(b) 有符號數除法指令IDIV(Signed Integer Divide Instruction)

指令的格式:IDIV Reg/Mem

受影響的標誌位:AF、CF、OF、PF、SF和ZF

指令的功能是用顯式運算元去除隱含運算元(都作為有符號數),所得商和餘數的對應關係見表5.3。

clip_image006[4]

5、型別轉換指令

在作有符號除法時,有時需要把短位數的被除數轉換成位數更長的資料型別。比如,要用BL中的資料去除AL,但根據除法指令的規定:除數是8位,則被除數必須是AX,於是就涉及到AH的取值問題。

為了方便說明,假設:(AH)=1H,(AL)=90H=-112D,(BL)=10H。

1)、在作除法運算前,必須處理AH的原有內容

假設在作除法時,不管AH中的值,這時,(AH、AL)/BL的商是19H,但我們知道:AL/BL的商應是-7,這就導致:計算結果不是所預期的結果,所以,在作除法運算前,程式設計師必須要處理AH中的值。

2)、作無符號數除法時

可強置AH的值為0,於是,可得到正確的結果。

3)、作有符號數除法時

如果強置AH為0,則AX=0090H,這時,AX/BL的商為9,顯然結果也不正確。

如果把AL的符號位1,擴充套件到AH中,得:AX=0FF90H=-112D,這時,AX/BL的商就是我們所要的正確結果。

綜上所述,因為在進行有符號數除法時存在隱含運算元資料型別轉換的問題,所以,系統提供了四條資料型別轉換指令:CBW、CWD、CWDE和CDQ。

(a)位元組轉換為字指令CBW(Convent Byte to Word)

指令的格式:CBW

該指令的隱含運算元為AH和AL。其功能是用AL的符號位去填充AH,即:當AL為正數,則AH=0,否則,AH=0FFH。

指令的執行不影響任何標誌位。

(b)字轉換為雙字指令CWD(Convent Word to Doubleword)

指令的格式:CWD

該指令的隱含運算元為DX和AX,其功能是用AX的符號位去填充DX。指令的執行不影響任何標誌位。

(c)字轉換為擴充套件的雙字指令CWDE(Convent Word to Extended Doubleword)

指令的格式:CWDE ;80386+

該指令的隱含運算元為DX和AX,其功能是用AX的符號位填充EAX的高字位。指令的執行不影響任何標誌位。

(d)雙字轉換為四字指令CDQ(Convent Doubleword to Quadword)

指令的格式:CDQ ;80386+

該指令的隱含運算元為EDX和EAX,指令的功能是用EAX的符號位填充EDX。指令的執行不影響任何標誌位。

例5.5 編寫程式段,完成下面計算公式,並把所得的商和餘數分別存入X和Y中(其中:A,B,C,X和Y都是有符號的字變數)。

(C - 120 + A*B) / C

解:

A DW ?

B DW ?

C DW ?

X DW ?

Y DW ?

MOV AX, C

SUB AX, 120D ;書寫指令“ADD AX, -120D”也可以

CWD

MOV CX, DX

MOV BX, AX ;(CX, BX)←(DX, AX),排程暫存器,為作乘法準備必要的暫存器

MOV AX, A

IMUL B ;(DX, AX)←A*B

ADD AX, BX ;計算32位二進位制之和,為作除法作準備

ADC DX, CX

IDIV C ;AX是商,DX是餘數

MOV X, AX ;分別儲存商和餘數到指定的字變數單元裡

MOV Y, DX