本文最初發表於2015-8-14,是由別的地方遷移過來的
(本文所講為無符號運算)
DIV指令是8086匯編中的除法運算指令,它的結果不是浮點數,而是兩個整數:商和余數。
我們來看王爽老師是怎么講的:
現在大家思考一下,為什么在匯編語言中,除數的長度比被除數少呢?
分析:
因為被除數長度若等於除數的長度(假設是8位),那么定義一個乘法的式子:X*Y=Z如果X=FF,Y=2時會發生什么?結果是Z=FE(原結果是1FE,但是溢出后只保留8位結果),這個結果顯然不能讓人接受。如果把這個式子化成除法,正確的就是1FE/FF=2。所以,將Z的長度擴長,問題就可以解決了。
把上述內容壓縮就是:
被除數的位數=除數的位數*2
除數是8位:(AX)/NUM=(AL)…(AH)
除數是16位:(DX(H)AX(L))/NUM=(AX)…(DX)
用法:DIV 除數
通過書上所講,我們又得出以下結論:
一個大於2^8 - 1(2的8次方減1)的數作被除數,被除數必須為16位,而除數為8位,商和余數也是8位的。一個大於2^16 - 1的數作被除數,被除數必須為32位,除數為16位,商和余數為16位。由於有些時候,CPU的寄存器可能無法滿足使用,這樣就需要用內存空間來做除法了。
首先,先要認識X ptr操作符,這個操作符是指明要處理的數據長度,它的用法很簡單:
byte ptr 處理數據長度為字節型
word ptr 處理數據長度為字型
mov byte ptr ds:[0],1H ;把立即數1H賦值給DS:[0]所指向的內存單元 mov word ptr ds:[0],1H ;把立即數 1H賦值給DS:[0]所指向的內存字單元
如果兩個例子執行前對應的內存單元都為0。
則第一個例子執行后內存單元是這樣的: DS:0000 01
第二個例子執行后內存單元是這樣的: DS:0000 01 00
現在我們來看一段代碼:
assume cs:code,ds:data data segment;數據段 db100D;設定一個除數內存單元,里面的數據是100,地址是ds:[0] data ends code segment;代碼段 start: mov ax,data mov ds,ax;設置數據段寄存器指向數據段 mov ax,200D;設置被除數 div byte ptr ds:[0];進行除法 mov byte ptr ds:[0],al;將結果覆蓋除數所在的內存單元 mov ax,4c00H;程序返回 int 21H code ends end start
代碼執行:
運行所有除法指令前的指令后內存單元和寄存器情況:
運行除法指令后並執行到程序返回之前內存單元和寄存器的情況:
此時結果已經保存到數據段中,程序完成。
匯編語言的除法指令很容易忘記其用法和結果保存的位置,需要多練習,多實踐。