汇编语言乘法和除法指令
文章目錄
- 1.乘法指令MUL/IMUL
- 2.除法指令DIV/IDIV
- 3.其他運算指令
乘法和除法指令
IA-32 處理器的乘法和除法指令需要區別無符號數和有符號數, 并隱含便用丁 EAX (和EDX) 寄存器。
1.乘法指令MUL/IMUL
基本的乘法指令指出源操作數 reg/mem (寄存器或存儲單元), 隱含使用目的操作數,表3。若源操作數是8位數8/m8,AL與其相乘得到16位積,存入AX中,若源操作數是 16 位數 r16/m16, AX 與其相乘得到 32 位積, 高 16 位存人 DX, 低 16 位存入AX中; 若源操作數是32位數r32/m32,EAX與其相乘得到64位積,高32位存人EDX,低32位存人EAX中。
表1
乘法 (multiplication) 指令分成無符號數乘法指令 MUL和有符號數乘法指令 IMUL。 同一個二進制編碼表示無符號數和有符號數時, 真值可能不同。
例如,用MUL進行8位無符號乘法運算:
mov al,0a5h;ALA5H,作為無符號整數編碼,表示真值:165
mov bl,64h;BL=64H,作為無符號整數編碼,表示真值:100
mul bl;無符號乘法:AX=4074H,表示真值:16500
再如, 用IMUL進行8位有符號乘法運算:
mov al,0a5h;AL=A5H,作為有符號整數補碼,表示真值:-91
mov bl,64h;BL=64H,作為有符號整數補碼,表示真值:100
imul bl;有符號乘法:AX=DC74H,表示真值:-9100
所以, 對二進制數乘法: A5H x64H, 如果把它們當作無符號數, 用 MUL指令的結果為4074H, 表示真值:16500。 如果采用IMUL指令, 則結果為DC74H, 表示真值: -9100。
注意 加減指令只進行無符號數運算,程序員利用CF和OF區別結果。
基本的乘法指令按如下規則影響標志OF和CF: 若乘積的高一半是低一半的符號位擴展, 說明高一半不含有效數值, 則OF=CF=0; 若乘積的高一半有效, 則用OF=CF=1 表示。 設置OF和CF標志的原因, 是有時我們需要知道高一半是否可以被忽略, 即不影響結果。
但是, 乘法指令對其他狀態標志沒有定義, 即任意、 不可預測。 注意, 這一點與數據傳送類指令對標志沒有影響是不同的, 沒有影響是指不改變原來的狀態。
從80186開始, 有符號數乘法又提供了兩種新形式, 如表1后兩行所示。 這些新增的乘法形式的目的操作數和源操作數的長度相同 (用于支持高級語言中類型一致的乘法運算), 因此乘積有可能溢出。 如果積溢出, 那么高位部分被丟掉, 并設置CF=OF=1; 如果沒有溢出, 則CF-OF=0。 后一種形式采用了3個操作數, 其中一個乘數用立即數表達。
由于存放積的目的操作數長度與乘數的長度相同, 而有符號數和無符號數的乘積的低位部
分是相同的, 所以 , 這種新形式的乘法指令對有符號數和無符號數的處理是相同的。
2.除法指令DIV/IDIV
除法指令給出源操作數 reg/mem (寄存器或存儲單元), 隱含使用目的操作數, 如表2
所示。
與乘法指令類似, 除法 (division) 指令也隱含使用 EAX (和 EDX), 并且被除數的位數要
倍長于除數的位數。 除法指令也分成無符號除法指令 DIV 和有符號除法指令IDIV。 有符號除法時, 余數的符號與被除數的符號相同。 對同一個二進制編碼, 分別采用 DIV 和 IDIV 指令后, 商和余數也會不同。
例如,用DIV進行8位無符號除法運算:
mov ax,400h;AX=400H,作為無符號整數編碼,表示真值:1024 X2M0
mov bl,0b4h:BL=B4H,作為無符號整數編碼,表示真值:180
div bl:無符號除法:商AL=05H,余數:AH=7CH(真值:124)
;表示計算結果:5x180+124=1024
再如, 用IDIV 進行8位有符號除法運算:
mov ax,400h;AX=400H,作為有符號整數補碼,表示真值:1024
mov bl,0b4h;BL=B4H,作為有符號整數補碼,表示真值:-76
idiv bl;有符號除法:商AL=F3H(真值:-13),余數:AH=24H(真值:36)
;表示計算結果:(-13)x(-76)+36=1024
除法指令使狀態標志沒有定義, 但是卻可能產生除法溢出。 除數為0或者商超出了所能表達的范圍, 則發生除法溢出。 用DIV指令進行無符號數除法, 商所能表達的范圍是: 字節量除時為0-255,字量除時為0~65535,雙字量除時為0-232-1。用IDIV指令進行有符號數除法,
商所能表達的范圍是:字節量除時為-128127,字量除時為-3276832767,雙字量除時
為-231~232 -1。 如果發生除法溢出,IA-32處理器將產生編號為0的內部中斷。實際應用中應該考慮這個問題, 操作系統通常只會提示錯誤。
3.其他運算指令
除基本的二進制加減乘除指令外,算術運算指令還包括十進制 BCD碼運算以及與運算相關的符號擴展等指令。
IA-32處理器支持8,16和32位數據操作,大多數指令要求兩個操作數類型一致。但是,實際的數據類型不一定滿足要求。例如,32位與16位數據的加減運算,需要先將16位擴展為32位。 再如,32位除法需要將被除數擴展成64位。 不過, 位數擴展后數據大小不能因此改變。
對無符號數據,只要在前面加0就實現了位數擴展、大小不變,這就是零位擴展(zeroextension), 對應指令 MOVZX, 如表3, 例如, 8位無符號敷據80H (128) 零位擴展為位0080H(-128).
MOVZX指令下
nov al.82h;AL=82H
movzx bx,al;AL=82H,零位擴展:BX=0082H
movzx ebx,a1:AL=82H,零位擴展:EBX=00000082H
對有符號數據, 需要進行符號擴展 (sign extension), 即用一個操作數的符號位 (最高位)形成另一個操作數, 對應指令MOVSX. 例如, 8位有符號數據64H(100) 為正數, 符號位為O, 符號擴展成16位是0064H(100)。 再如,16位有符號數據 FFOOH( -256) 為負數, 符號位為1, 符號擴展成32位是FFFFFFOOH (- -256). 特別典型的例子是真值-1, 字節量補碼表達是FFH, 字量補碼表達是FFFFH,雙字量補碼表達是FFFFFFFFH.
MOVSX指令舉例如下:
mov al,82h;AL=82H
movsx bx,al;AL=82H,符號擴展:BX=FF82H
movsx ebx,al;AL=82H,符號擴展:EBX=FFFFFF82H
零位擴展對應無符號數, 符號擴展對應有符號數, 它們使數據位數加長, 但數據大小井設有改變。 另外, 還可以使用符號擴展指令CBW、 CWD, CWDE 和CDQ, 它們的功能分別是將AL符號擴展為AX、 AX符號擴展為DX和AX、 AX符號擴展為EAX、 EAX符號擴展為EDX和 EAX。 Intel 8086 只支持 CBW 和 CWD 指令, 不支持包括 MOVZX 和 MOVSX 在內的其他擴展。
總結
以上是生活随笔為你收集整理的汇编语言乘法和除法指令的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 2020 5G场景化应用案例TOP20
- 下一篇: ZCMU-1550-AA