如何修复此代码以便执行“使用减法除法”

时间:2019-05-01 18:57:13

标签: assembly division subtraction masm32

我的程序应该使用减法执行除法运算。但是,我得到的都是废话结果。有人可以帮我处理我的程序和其中的循环吗? 谢谢。

my_user_id

1 个答案:

答案 0 :(得分:2)

只要没有借入,您就继续减去。如果发生借用,您的计数为:

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

编辑

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

这个简单的解决方案可以完成工作,但是对于大商来说它的速度慢得令人无法接受。这就要求有一个更好的解决方案,而不要背叛“通过使用减法进行除法”(也就是“不要使用div(或任何类似的指令)”的任务。

为了模仿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)坐标