📄 div.asm
字号:
;
;-----> Division loop
;
d3: cmp esi,14
jb d3a
push edi
mov edx,a[ebp][esi] ; uj unshifet in dx (hiWord)
mov eax,a[ebp][esi-4] ; uj+1 unshifted
mov ebx,a[ebp][esi-8] ; uj+2 unshifted
mov edi,a[ebp][esi-12] ; uj+3 unshifted
push ecx
mov cx,d[ebp]
@@: cmp cx,0
je @F
rcl edi,1
rcl ebx,1
rcl eax,1
rcl edx,1
dec cx
jmp @B
@@: pop ecx
pop edi
jmp qhat
;
d3a: mov edx,a[ebp][esi] ; uj unshifted
mov eax,a[ebp][esi-4] ; uj+1 unshifted
mov ebx,a[ebp][esi-8] ; uj+2 unshifted
push ecx
mov cx,d[ebp]
@@: cmp cx,0
je @F
rcl ebx,1
rcl eax,1
rcl edx,1
dec cx
jmp @B
@@: pop ecx
;
;-----> Calculate and test qhat
;
qhat: mov uj1[ebp],eax ; Store shifted uj+1
mov uj2[ebp],ebx ; Store shifted uj+2
mov ebx,v1[ebp] ; v1 in bx
cmp ebx,edx
je bm1 ; If v1 = uj then q = b - 1
;
div ebx ; eax <- qhat
; ; edx <- rhat: = uj*b + uj+1 -qhat*v1 = (uj*b + uj+1) mod v1
mov q1[ebp],eax ; store qhat intermediately
cmp eax,0
jne @F
jmp dml ; If q=0 process next digit
;
bm1: mov eax,0ffffffffh ; eax <- qhat
mov q1[ebp],eax ; Store qhat intermediately
mov edx,uj1[ebp] ; edx <- uj+1
add edx,v1[ebp] ; edx <- uj+1 + v1 =: rhat
jc d4 ; rhat >= b => v2 * qhat < rhat * b
;
@@: mov ebx,edx ; ebx <- rhat
mul dword ptr v2[ebp] ; eax <- low(qhat * v2), edx <- high(qhat * v2)
cmp edx,ebx ; rhat >= high(qhat * v2) ?
jb d4 ; CF == 1? Then finished
ja @F ; rhat < high(qhat * v2) => reduce qhat
cmp eax,uj2[ebp] ; uj+2 >= low(qhat * v2) ?
jbe d4 ; CF == 1 OR ZF == 1? Then finished
;
@@: dec dword ptr q1[ebp] ; Correcting qhat by decrementing
add ebx,v1[ebp] ; ebx <- rhat + v1
jc d4 ; rhat >= b => v2 * qhat < rhat * b
sub eax,v2[ebp] ; (qhat * v2) - v2
sbb edx,0
;
cmp edx,ebx ; rhat >= high(qhat * v2) ?
jb d4 ; CF == 1? Then finished
ja @B ; rhat < high(qhat * v2) => reduce qhat
cmp eax,uj2[ebp] ; uj+2 >= low(qhat * v2) ?
ja @B ; CF==0 + ZF==0? => repeat decrement of qhat
;
d4: push ecx ; Store main counter
push esi ; Store j + l(b)
push edi ; Store j
mov cx,b[ebp] ; Load counter with l(b)
shr cx,1
jnc d4a
inc cx
d4a: mov ebx,q1[ebp] ; q in bx
mov esi,2
mov edx,0 ; Dummy carry
;
;-----> Multiplication and subtraction
;
dms: push edx
mov eax,ebx ; q in ax
mul dword ptr b[ebp][esi] ; hi:dx lo:ax
sub a[ebp][edi],eax
adc edx,0 ; Carry to next subtrahend
pop eax
sub a[ebp][edi],eax
adc edx,0 ; Carry to next subtrahend
inc edi
inc edi
inc edi
inc edi
inc esi
inc esi
inc esi
inc esi
loop dms
sub a[ebp][edi],edx
jnc dnc ; No correction necessary if carry = 0
;
;-----> Correction
;
pop edi
push edi
xor ecx,ecx
mov cx,b[ebp] ; Load counter with l(b)
shr cx,1
jnc d4b
inc cx
d4b: mov esi,2
clc
d5: mov eax,b[ebp][esi] ; b[i]
adc a[ebp][edi],eax ; a[j+i] + b[i]
inc edi
inc edi
inc edi
inc edi
inc esi
inc esi
inc esi
inc esi
loop d5 ; Outer loop
jnc d51
inc dword ptr a[ebp][edi]
d51: dec dword ptr q1[ebp] ; q = q - 1
;
;
dnc: pop edi ; Get pointers and counters
pop esi
pop ecx
dml: mov eax,q1[ebp] ; Get q
mov q[ebp][edi],eax ; q[j] = q
sub edi,4
sub esi,4
dec ecx ; Inner loop
jz d6
jmp d3
;
d6: pop edi ; Get l(a)-l(b)-1 (ULONG digits)
add edi,2 ; di points to low-order byte of last USHORT
mov eax,0
@@: cmp ax,q[ebp][edi] ; q[l(a)-l(b)]=0 ?
jne d7 ; If so...
dec edi
dec edi ; ...l(q) = l(a) - l(b) - 1
cmp edi,0
jne short @B
d7: mov edx,edi
shr edx,1 ; l(q) (#USHORTs) in dx
mov q[ebp],dx ; Store l(q)
;
;-----> Calculate length of remainder
;
mov eax,0
mov ax,b[ebp]
mov ecx,eax
shl ax,1
mov edi,eax
mov ebx,0
inc edi
inc edi
d8: dec edi
dec edi ; di points to low-order byte of a[l(b)]
cmp a[ebp][edi],bx
loope d8
jz d9 ; If a[bp][di]!= 0...
inc cx ; ...l(r) has to be incremented
d9: mov a[ebp],cx ; Store l(r)
;
;-----> Store results
;
dstore: mov esi,ebp
mov ebx,ebp
pop ebp
push esi
add esi,q
mov edi,_qot ; Destination offset of quotient
mov ecx,0
mov cx,[esi]
shr cx,1
jnc @F
inc cx
@@: cld
cmp cx,0
je qzero
rep movsd
qzero: movsw
;
;-----> Store remainder
;
pop esi
drs:
mov edi,_rst
add esi,a
mov ecx,0
mov cx,[esi]
shr cx,1
jnc @F
inc cx
@@: cld
cmp cx,0
je rzero
rep movsd
rzero: movsw
mov eax,0 ; Return-Value = 0: Everything OK
;
;*******************************************************************************
; Security: Purge stack memory
divret: mov edi,ebx
mov ecx,(WORKSP-4)/4
cld
rep stosd ; Overwrite with 0 or -1
;*******************************************************************************
;
pop esi
pop edi
pop ebx
mov esp,ebp
pop ebp
ret
;
;
divz: mov eax,0 ; Return-Value = 0: Everything OK
mov edi,_rst ; Destination Offset of remainder
mov esi,_qot ; Destination offset of quotient
mov [edi],ax ; Remainder = 0
mov [esi],ax ; Quotient = 0
jmp short divret
;
divbyz: mov eax,-1
jmp short divret ; Return-Value = -1: Division by zero
;
;-----> Case q = 0 and r = a
;
dra: mov esi,ebp
mov ebx,ebp
pop ebp
mov edi,_qot
mov word ptr [edi],0 ; q = 0
jmp short drs ; Store remainder
;
;
;>>>>>> Short Division
;
;
dshort: mov ecx,0
mov cx,a[ebp]
shr cx,1
jnc dsh0
inc cx
dsh0: mov edi,ecx
shl edi,2
sub edi,2
mov edx,0
mov ebx,b[ebp+2]
dsh1: mov eax,a[ebp][edi]
div ebx
mov q[ebp][edi],eax
sub edi,4
loop dsh1
dsh2: mov ecx,0
mov cx,a[ebp]
mov esi,ecx
shl esi,1
@@: mov bx,q[ebp][esi]
cmp bx,0
jne dsh3
dec esi
dec esi
dec ecx
cmp cx,0
jne short @B
dsh3: mov q[ebp],cx
mov a[ebp+2],edx
mov word ptr a[ebp],2
cmp word ptr a[ebp+4],0
jne dst
mov word ptr a[ebp],1
cmp word ptr a[ebp+2],0
jne dst
mov word ptr a[ebp],0
dst: jmp dstore
;
div_l endp
END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -