如何修复此代码以执行 "Division by using Subtracting"

How to fix this code in order to perform "Division by using Subtracting"

我的程序应该使用减法来执行除法。但是,我得到无意义的结果作为输出。有人可以帮助我完成我的程序和内部循环吗? 谢谢。

div proc
pushad

mov ecx,firstInt
mov ebx,0
subtracting:
    sub ebx,secondInt
loop subtracting
mov divResult,ebx
popad
ret
divt endp

只要没有借位,你就可以继续减法。如果发生借用,您有计数:

    mov     ecx, firstInt
    mov     ebx, -1
subtracting:
    inc     ebx
    sub     ecx, secondInt
    jnb     subtracting
    mov     divResult, ebx

编辑

上面的代码仍然缺少的是检查除数是否为零。如果我们允许使用零分隔符,代码将永远 运行 因为减去零永远不会产生借位!

这个简单的解决方案可以完成工作,但对于大商来说速度慢得令人无法接受。这需要一个更好的解决方案,当然不会背叛 "Division by using subtracting" aka "Don't use div (or any similar instruction)".

的任务

为了模仿div指令:

divide:
    mov     eax, firstInt
    xor     edx, edx
    div     secondInt       ; -> EDX is remainder, EAX is quotient

我们可以这样写:

simple:
    mov     edx, firstInt
    mov     eax, -1
.A: inc     eax
    sub     edx, secondInt
    jnb     .A
    add     edx, secondInt  ; -> EDX is remainder, EAX is quotient

这个简单解决方案的问题在于我们可能会多次减去一个小数。如果我们能找到一种方法一次减去更多呢?
我们可以,如果我们减去除法器的二进制倍数(*1、*2、*4、*8、*16、...)。这些因素的总和将产生商。

计算例如503 / 20 我们将减去以下内容:

503 - (20 * 16) = 183
183 - (20 *  8) =  23
 23 - (20 *  1) =   3 <-- is remainder
            --
            25 <-- is quotient

在代码中:

complex:
    mov     edx, firstInt
    xor     eax, eax
    jmp     .C
.A: rol     ecx, 1
    shl     ebx, 1
    jc      .B
    cmp     ebx, edx
    jbe     .A
.B: rcr     ebx, 1
    add     eax, ecx
    sub     edx, ebx
.C: mov     ebx, secondInt
    mov     ecx, 80000000h
    cmp     edx, ebx
    jnb     .A
; -> EDX is remainder, EAX is quotient

为了说明开发更好的解决方案的重要性,我对几个部分进行了计时:

                       simple      complex    divide
                   --------------  --------  --------
4294967295 /   1   8087730.0 µsec  3.0 µsec  0.3 µsec
2147483648 /  10    405994.0 µsec  1.3 µsec  0.1 µsec
     47623 / 320         0.4 µsec  0.2 µsec  0.1 µsec
  • 4294967295 / 1是最坏情况除法
  • 2147483648 / 10用于开始显示号码2147483648
  • 47623 / 320用于将一个320x200的256色视频模式偏移地址47623转换成(x,y)坐标