我的程序应该使用减法执行除法运算。但是,我得到的都是废话结果。有人可以帮我处理我的程序和其中的循环吗? 谢谢。
my_user_id
答案 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)坐标