无法理解为什么某些变量被改变了

问题描述 投票:0回答:1

我的任务是创建一个程序,在用户识别的范围内列出复合数字。为了确定一个数字是否是复合数,我将除以它并检查余数为零。我的实际问题是尝试在我的代码中打印名为“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。

assembly masm irvine32
1个回答
1
投票

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以找到高达足够值的奇数复合,然后循环打印每个偶数,以及奇数如果它们的位图或字节图条目将更有效筛在筛子里。

© www.soinside.com 2019 - 2024. All rights reserved.