我的程序应该通过使用减法执行除法。但是,我得到了无意义的结果作为输出。有人可以帮助我处理我的程序和循环吗?谢谢。
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
编辑
上面的代码仍然缺少的是检查分频器是否为零。如果我们允许零分频器,代码将永远运行,因为减零将永远不会产生借用!
这个简单的解决方案可以完成工作,但对于大商而言,速度慢得令人无法接受。这需要一个更好的解决方案,当然不要背叛“使用减法划分”的任务,即“不要使用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
用于开始显示数字214748364847623 / 320
用于将320x200 256色视频模式偏移地址47623转换为(x,y)坐标