实验10.2
1. 解决除法溢出的问题
- 被除数是 16 位, 除数是 8 位。在这种情况下, 被除数放在 ax 中, 除数放在 8 位 reg 或者内存单元中。产生的结果:商放在 al 中, 余数放在 ah 中
- 被除数是 32 位, 除数是 16 位。在这种情况下, 被除数的高 16 位放在 dx 中, 低 16 位放在 ax 中, 除数放在 16 位 reg 或者内存单元中。产生的结果:商放在 ax 中, 余数放在 dx 中。
功能:进行不会产生溢出的除法运算, 被除数为 dword 型, 除数为 word 型, 结果为 dword 型。 参数: (ax)=dword 型数据的低 16 位 (dx)=dword 型数据的高 16 位 (cx)=除数 返回: (dx)=结果的高 16 位 (ax)=结果的低 16 位 (cx)=余数
2. 溢出的情况
assume cs:code,ds:data,ss:stack
data segment
dd 1234567 ; 除以100, 余数67, 16进制43
data ends
stack segment stack
db 128 dup(0)
stack ends
code segment
start:
mov ax, stack
mov ss,ax
mov sp,128
mov bx,data
mov ds,bx
mov ax, ds:[0]
mov dx, ds:[2]
; mov bx,100 ; 不溢出的情况 1234567 / 100 = 12345(3039H), 余数67(43H)
; AX=D687 BX=0064 CX=00AE DX=0012 SP=0080 BP=0000 SI=0000 DI=0000
; DS=0E24 ES=0E14 SS=0E25 CS=0E2D IP=0017 NV UP EI PL NZ NA PO NC
; 0E2D:0017 F7F3 DIV BX
; -t
; AX=3039 BX=0064 CX=00AE DX=0043 SP=0080 BP=0000 SI=0000 DI=0000
; DS=0E24 ES=0E14 SS=0E25 CS=0E2D IP=0019 NV UP EI PL NZ NA PO NC
mov bx,10 ; 溢出的情况 1234567 / 10
; AX=D687 BX=000A CX=00AE DX=0012 SP=0080 BP=0000 SI=0000 DI=0000
; DS=0E24 ES=0E14 SS=0E25 CS=0E2D IP=0017 NV UP EI PL NZ NA PO NC
; 0E2D:0017 F7F3 DIV BX
; -t
; AX=D687 BX=000A CX=00AE DX=0012 SP=007A BP=0000 SI=0000 DI=0000
; DS=0E24 ES=0E14 SS=0E25 CS=F000 IP=CA60 NV UP DI PL NZ NA PO NC
div bx
mov ax,4c00h
int 21h
code ends
end start
3. 实验 10.2
assume cs:code,ds:data,ss:stack
; 32bit div => ax = low 16 bit, dx = high 16bit
; ax 保存结果, dx 保存余数
; 思路:伪代码, 比如 35
; 3是高位, 给dx
; 5是低位, 给ax
; 3/2=1...1, 商1, push保存起来, 余数1给dx
; ax:dx 重新组成一个数, ax:dx / 2
; dx = 新余数, 给cx
; ax = 新的商
; dx = pop 保存的商1
; 此时:
; ax = 新的商
; dx = 旧的商
; cx = 新余数
data segment
dd 1234567 ; 除以100, 余数67, 16进制43
data ends
stack segment stack
db 128 dup(0)
stack ends
code segment
start:
mov ax, stack
mov ss,ax
mov sp,128
mov bx,data
mov ds,bx
call div_number
mov ax,4c00h
int 21h
;===========================
long_div:
mov ax, dx
mov dx,0
div cx ; dx = 余数
push ax ; 保存第一次除的结果
mov ax,ss:[bp] ; 取出保存的低16bit
div cx ; dx:ax / cx, dx:余数, ax:低16位, 重新组合一个数除cx
; AX=D687 BX=0E24 CX=000A DX=0008 SP=0078 BP=007C SI=0000 DI=0000
; DS=0E24 ES=0E14 SS=0E25 CS=0E2D IP=0020 NV UP EI PL NZ NA PE NC
; 0E2D:0020 F7F1 DIV CX
; -t
; AX=E240 BX=0E24 CX=000A DX=0007 SP=0078 BP=007C SI=0000 DI=0000
; DS=0E24 ES=0E14 SS=0E25 CS=0E2D IP=0022 NV UP EI PL NZ NA PE NC
; 0E2D:0022 8BCA MOV CX,DX
mov cx, dx ; dx = 余数, 给 cx
pop dx ; 取出商给dx
; AX=E240 BX=0E24 CX=0007 DX=0007 SP=0078 BP=007C SI=0000 DI=0000
; DS=0E24 ES=0E14 SS=0E25 CS=0E2D IP=0024 NV UP EI PL NZ NA PE NC
; 0E2D:0024 5A POP DX
; -t
; AX=E240 BX=0E24 CX=0007 DX=0001 SP=007A BP=007C SI=0000 DI=0000
; DS=0E24 ES=0E14 SS=0E25 CS=0E2D IP=0025 NV UP EI PL NZ NA PE NC
; 0E2D: 0025 C3 RET
; (dx)= 结果的高 16 位 = 0001
; (ax)= 结果的低 16 位 = E240
; (cx)= 余数
; 1E240H = 123456(10) = 1234567/10...7, cx = 7, 满足题目要求
ret
;===========================
div_number:
mov ax, ds:[0]
mov dx, ds:[2]
mov cx, 10 ; 除数, 1234567 / 10
push ax ; 低16bit
mov bp,sp ; ss:[bp] = AX = 低16bit
call long_div
add sp,2 ; call 的时候,push了
ret
code ends
end start