因为DX:AX除以一个16位数,得到的商放在AX,余数放在DX,由于32位除以16位数商可能超过16位,会出现divide overflow,所以我给限定在0~655350之间,这样的话最大655350/10=65535=FFFF也保持在16位之内(显示10进制要除10取余显示)
ps::解决的办法不是没有,可以自己写个子过程专用来做除法(减法代替除法)
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
data segment
MUL1 db 36H,35H,34H,32H,31H 被乘数
COUNT1 equ $-MUL1
end1 db '$'
MUL2 db 38H 乘数
COUNT2 equ $-MUL2
end2 db '$'
data ends
code segment
assume cs:code,ds:data
start:
mov ax,data
mov ds,ax
mov dx,offset MUL1
mov ah,9
int 21h
mov dl,'*'
mov ah,2
int 21h
mov dx,offset MUL2
mov ah,9
int 21h
mov dl,'='
mov ah,2
int 21h
mov si,offset MUL1 装载第一个数放到ax
mov cx,COUNT1
call LoadValue
mov ax,dx
mov si,offset MUL2 装载第二个数放到bx
mov cx,COUNT2
call LoadValue
mov bx,dx
mul bx
call ShowInt 显示32位数
mov ah,4ch
int 21h
显示DX:AX表示的32位整数
入口: dx:ax 待显示的整数(0~655350)
ShowInt proc near
push dx
push cx
push bx
push ax
pushf
and dx,0fh
mov cx,6 0~655350最多6位
mov bx,0ah
lp_si:
div bx
push dx 得到的是低到高位,要改下顺序显示出来
mov dx,0
loop lp_si
mov cx,6 开始输出
lp_sis:
pop dx
add dl,30h
mov ah,2
int 21h
loop lp_sis
popf
pop ax
pop bx
pop cx
pop dx
ret
ShowInt endp
字节中的数字装入寄存器
入口: si 数字字节的起始地址
cx 数字位数
出口: dx 数值
LoadValue proc near
push si
push cx
push bx
push ax
pushf
xor bx,bx
lp_lv:
xchg ax,bx
mov dx,0ah
mul dx
xchg bx,ax
and ax,0
mov al,byte ptr[si]
sub al,30h
add bx,ax
inc si
loop lp_lv
mov dx,bx
popf
pop ax
pop bx
pop cx
pop si
ret
LoadValue endp
code ends
end start
下面是32位无符号数乘16位的无符号数的计算子程序,解决8086本身指令无法解决的问题。其实如果在没有乘法指令mul时,就是采用移位相加的方法来实现乘法运算的 !
对于有符号数的乘法运算,是对负数求补后当作无符号数计算,计算完后在来处理符号。
无符号乘法子程序 (mul指令只能实现16位乘16位,本子程序实现32位乘16位--限定数的大小,结果仍为32位)
被乘数放置于dx,ax 中, 乘数放置于 bx中
结果放置于dx,ax中(dx为高16位,ax为低16位)
MULT PROC NEAR
PUSH BX
PUSH CX
PUSH SI
PUSH DI
PUSH BP
PUSHF
MOV SI,0
MOV DI,0
CMP BX,0
JE @MULTEXIT
@MULT1: SHR BX,1
JNC @MULT2
ADD SI,AX
ADC DI,DX
@MULT2: SHL AX,1
RCL DX,1
CMP BX,0
JNE @MULT1
MOV DX,DI
MOV AX,SI
POPF
POP BP
POP DI
POP SI
POP CX
POP BX
RET
@MULTEXIT:
MOV AX,0
MOV DX,0
POPF
POP BP
POP DI
POP SI
POP CX
POP BX
RET
MULT ENDP
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)