Невозможно ввести цикл в сборке из-за возможного неправильного сравнения - PullRequest
0 голосов
/ 07 ноября 2019

Я пытаюсь написать код в ассемблере, который будет печатать правильную последовательность, пока не будет достигнута введенная итерация. Я не могу войти в цикл for, я не уверен, почему, однако, это может быть связано с неправильным использованием вызова cmp <dst>, <src> - я не думаю, что именно поэтому, но это может быть.

Мой раздел данных выглядит следующим образом:

.data
    stmt1 db "Nathanial Mendes", 0Ah, 0

    prompt1 db "Enter maximum sequence count: ", 0
    fmt db "%d", 0

    sum db "Fib(%d) = %d", 0

    seq dd 0

Вот так выглядит мой раздел кода

.code 
    main PROC c
    push offset stmt1
    call printf

    ;Prompt for first int
    push offset prompt1
    call printf
    add esp, 4

    push offset seq
    push offset fmt
    call scanf
    add esp, 8

    ;Set up loop vars
    mov eax, 0 ; set i = 0
    mov ebx, 0
    mov ecx, 0
    mov edx, 0

;#############################
    beginloop:
    cmp eax, seq ; comparing the counter (eax) to the max iteration (seq) 
    jle endloop ; if it is false jump to the end of the loop

;#######
    ;code for Fib here

    ;print statement (prints out the current Fib, looks like Fib(iteration) = Fib_sum
    push eax
    push ebx
    push offset sum
    call printf
    add esp, 8

    ;next term calculations for the fib seq.
    add ecx, edx
    mov ebx, ecx
    mov ecx, edx
    mov edx, ebx
;#######
    ; set up next iteration of for-loop

    add eax, 1 ; add one to the iterator 
    jmp beginloop
;#######
    ;when the for loop is false
    endloop:

    ;Print (final) result
    push eax
    push ebx
    push offset sum
    call printf
    add esp, 8

;##########################################

    INVOKE ExitProcess,0
    main endp
end

Почему мой цикл for никогда не идетпосле оператора сравнения и переходит непосредственно к вызову endloop?

1 Ответ

1 голос
/ 07 ноября 2019

cmp eax, seq / jle endloop - это if(i<=seq) break с i=0. Так что для неотрицательных seq вы никогда не входите в цикл.

Вы хотите противоположное условие разрыва. Или поместите это условие цикла в bottom вашего цикла, как обычный asm-цикл с условным переходом внизу. ( Почему циклы всегда компилируются в стиле "do ... while" (прыжок в хвост)? )

Как прокомментировал Шестер, в вашем коде есть другие ошибки, но это ответ на этот вопрос. ,(Я думаю, что Шут считает его «входящим в цикл» один раз, когда выполнение проходит метку beginloop: и достигает вашего if() break в верхней части тела цикла.)

Это похоже на синтаксис MASM, так что seq без [] по-прежнему является операндом памяти, не сравниваемым с адресом как непосредственным. Я бы вообще рекомендовал использовать [] вокруг операндов памяти в целом.

...