0

x86アセンブリでGCDを繰り返し見つけようとしています。どういうわけか、残り = 0 であるため、ループは最初の反復後に終了し続けます。理由はありますか?

;while r > 0 do
;   Set b = a
;   Set a = r
;   Set r = b % a
;Output a


calculation_loop:
    cmp     remainder, 0                    ;check if remainder is 0
    je      end_of_calc                     ;if it is, value in intA is GCD

    mov     ecx, intA                       ;set b = a
    mov     intB, ecx

    mov     ecx, remainder                  ;set a = r
    mov     intA, ecx

    mov     edx, 0                          ;clearing remainder

    mov     ecx, intA                       ;process remainder and store in variable
    div     ecx
    mov     remainder, edx


    mov     eax, remainder
    call    WriteInt
    call    Crlf

    jmp     calculation_loop

end_of_calc:

    call    Crlf
    mov     eax, intA
    mov     edx, OFFSET outputPrompt
    call    WriteString
    call    WriteInt
    call    Crlf
4

1 に答える 1

0

remainderの最初の繰り返しに到達する前に 0 に設定されているに違いありません。そのため、すぐにcalculation_loop飛び出しています。calculation_loopそれはあなたの問題ですが、解決策はどうですか?

ループではdo-whileなく のように機能するように、コードの順序を変える必要があります。コードがループwhileのように機能するように、命令を並べ替えました。do-while

; calculation loop
calculation_loop:
    ; set b to a
    mov ecx, intA
    mov intB, ecx
    ; set a to r
    mov ecx, remainder
    mov intA, ecx
    ; clear remainder (I don't think this is nessesary, can't say for sure)
    mov edx, 0
    ;process remainder and store in variable
    mov ecx, intA                       
    div ecx
    mov remainder, edx
    ; write data
    mov eax, remainder
    call WriteInt
    call Crlf
    ; if the remainder != 0, go again
    cmp remainder, 0
    jne calculation_loop

剰余が計算された、ループの最後で剰余チェック ジャンプを行う方法に注目してください。うまくいけば、これで問題が解決します。

注: x86 で整数除算がどのように行われたか覚えていないため、他のコードに誤りがある可能性があるかどうかはわかりません。しかし、条件付きジャンプの順序付けに関する問題は解決したと思います。

最後に、もう1つのヒント。この種の数値処理コードを作成している場合、バグを見つけるには、一度にコード命令をステップ実行し、レジスターがどのように変化するかを (デバッガーを介して) 確認するのが最適な方法です。まだこれを行っていない場合は、強くお勧めします。

于 2013-06-13T01:41:34.720 に答える