多字节除法--汇编实现原理
长除法适用于整式除法、小数除法、多项式除法(即因式分解)等较重视计算过程和商数的除法,过程中兼用了乘法和减法。
长除法与手工计算除法方法一致。
以8592÷24为例:
从计算过程可以看出,长除法有以下特点:
1、必须先确定除数的位数
2、每一次试商的过程至少要进行一次减法,减法的次数取决于被除数和除数。
2.2 二进制除法
2.2.1 理论分析
这种算法将被除数和除数看成是二进制(虽然计算机里存的本来就是二进制),以二进制形式参与运算。这个算法的本质其实跟长除法相同,只不过长除法每次整体左移4位,二进制除法每次左移一位。另外,每次移位后只用做一次减法,而长除法可能需要多次减法。
以9÷3来说明:
算法思想及流程:
1、余数和商清零
2、将被除数高位移入余数中
3、将余数减去除数
4、如果小于0,则置商值低位为0
如果大于等于0,则置商值低位为1,并将相减的结果放入余数中
5、将商值左移1位;余数左移1位
6、判断是否循环完成(如果被除数是8bits,则循环8次)
7、没有则跳到步骤2继续执行
8、完成则存入商值和余数
仍以9÷3为例来说明计算步骤:
9 = 00001001 B;3 = 00000011 B
1、00000000-00000011小于0,商值为00000000
2、00000000-00000011小于0,商值为00000000
3、00000000-00000011小于0,商值为00000000
4、00000000-00000011小于0,商值为00000000
5、00000001-00000011小于0,商值为00000000
6、00000010-00000011小于0,商值为00000000
7、00000100-00000011大于0,商值为00000001,余数为00000001
8、00000011-00000011等于0,商值为00000011,余数为00000000
2.2.2 程序实现
tenx汇编(被除数和除数均为32位):
;////////////////////////////////////////////////////////////////
;Function: 32Bits/32Bits除法
;Description: 占用寄存器R0~R3
;Input: T21S_ADDR,TG2S_ADDR
;Output:
;余数存储在YuShu
;商存储在NW2_ADDR
;T21S_ADDR/TG2S_ADDR
;//////////////////////////////////
;//调用示例
; CALL A_DIV_B
;------------------------------
;////////////////////////////////////////////////////////
A_DIV_B:
LDS R0,$0
SHLX
SETDAT NW2_ADDR
A_DIV_B_ClrRAMLoop: ;//余数和商清零
MRW# @HL,G_RegLow
INC* R0
JNC A_DIV_B_ClrRAMLoop ;//16个RAM(余数和商)
LDS R2,$0
A_DIV_BLoop: ;//除法循环32位循环32次
SHLX ;//被除数移位
SETDAT T21S_ADDR
RF RF_CF
CALL RLC8RAM
A_DIV_B_YuShuRLC: ;//余数移位,低位来自被除数
SHLX
SETDAT YuShu
CALL RLC8RAM
SZRX
SETDAT YuShu
RZR HL_BACKUP_MODE_MUL2
A_DIV_B_ShangRLC:
SHLX
SETDAT NW2_ADDR
RF RF_CF
CALL RLC8RAM
A_DIV_B_YuShuSUBChuShu: ;//余数减除数
SHLX
SETDAT TG2S_ADDR ;//除数
RHL HL_BACKUP_MODE_MUL2
MZR HL_BACKUP_MODE_MUL2
LDS R0,$0
LDS R1,1000B
A_DIV_B_YuShuSUBChuShuCheckLoop: ;//判断@ZR与@HL大小
MRA R1
LDA# @HL
SBC# @ZR
MAF R1
INC* R0
JB3 A_DIV_B_YuShuSUBChuShuCheckLoopOver ;//8=1000B
JMP A_DIV_B_YuShuSUBChuShuCheckLoop
A_DIV_B_YuShuSUBChuShuCheckLoopOver:
MRA R1
JC A_DIV_B_YuShuSUBChuShuBig ;//@ZR>=@HL
LDS R0,1110B
AND* NW2_ADDR
JMP A_DIV_B_CheckLoop
A_DIV_B_YuShuSUBChuShuBig:
LDS R0,0001B
OR* NW2_ADDR
MHL HL_BACKUP_MODE_MUL2
MZR HL_BACKUP_MODE_MUL2
LDS R0,$0
LDS R1,1000B
A_DIV_B_YuShuSUBChuShuLoop:
MRA R1
LDA# @HL
SBC*# @ZR
MAF R1
INC* R0
JB3 A_DIV_B_CheckLoop
JMP A_DIV_B_YuShuSUBChuShuLoop
INC* R2
ADCI* R3,$0
JB1 A_DIV_B_Exit ;//32=10 0000B
JMP A_DIV_BLoop
A_DIV_B_Exit:
RTS
////////////////////////////////////////////////////////////////
;Function: 一个32bits数据左移一位
;Description: 调用完后,HL+8
;Input:
;Output:
;//////////////////////////////////
;//调用示例
; SHLX
; SETDAT YuShu
; CALL RLC8RAM
;------------------------------
;////////////////////////////////////////////////////////
RLC8RAM:
RLC# @HL
RLC# @HL
RLC# @HL
RLC# @HL
RLC# @HL
RLC# @HL
RLC# @HL
RLC# @HL
RTS