我的任务是创建一个程序,在用户识别的范围内列出复合数字。为了确定一个数字是否是复合数,我将除以它并检查余数为零。我的实际问题是尝试在我的代码中打印名为“current”的变量。 current初始化为3,然后每个循环递增,所以我希望首先打印数字4,但先打印2个。这怎么可能,当前永远不会达到2,它只会从3增加。
mov ecx, terms
trial:
inc current
mov eax, current
cdq
mov ebx, 2
div ebx
cmp edx, 0
je composite
cmp edx, 0
jg below
composite:
mov edx, OFFSET current
call WriteDec
call CrLf
below:
loop trial
如果我输入9,我希望打印4,6和8,因为当除以2时,这些都会留下0的余数,而是打印出2,3,4,5和6。
WriteDec takes its arg in EAX。它正在打印,而不是您放入EDX的指针(!)。 WriteDec按值取整数
当你第一次打电话给WriteDec
时(在3之后的第一个偶数),EAX = 4/2 = 2
,这就是你打印的内容。使用调试器来查看寄存器,您可能已经在EAX中看到了2
。
顺便说一句,你的循环只检查偶数,而不是所有复合数。 (而且你是以一种非常低效的方式做到的。即使是微不足道的,只需要test al,1
来测试EAX的低位。这个版本已经准备好让我们在排除偶数后扩展到试验循环,但是现在最简单的分支只是印刷或不印刷。
mov ecx, terms
mov ebx, current
trial: ; do {
inc ebx
test bl, 1
jnz odd ; low bit set = not divisible by 2 = odd
;; TODO: trial division loop after ruling out even numbers
;; mov eax,ebx
;; xor edx,edx
;; div something in a loop
even:
mov eax, ebx ; WriteDec takes an arg in EAX, and preserves all others
call WriteDec
call CrLf
odd:
cmp ebx, ecx
jb trial ; }while(current < terms)
;; The loop instruction is inefficient, don't bother with it
;; and you don't need a down-counter for the loop anyway
;; you already have terms
mov current, ebx ; in case you care?
检查复合材料的最简单方法是试验部门:Checking if a number is prime in NASM Win64 Assembly。
如果要将所有复合打印到一定数量,运行Sieve of Eratosthenes以找到高达足够值的奇数复合,然后循环打印每个偶数,以及奇数如果它们的位图或字节图条目将更有效筛在筛子里。