2

私はアセンブリにかなり慣れていないので、特定の数値の素因数分解を出力しようとしています。ネットを何時間も探し回った結果、DIV 命令に関する役立つ情報をいくつか見つけましたが、自分のコードで自分のやりたいことを実行することができません。

私はひどく間違ったことをしましたが、それを見つけることはできません。誰か親切な人が私にそれを見つけてくれませんか?

.data
myMessage BYTE "Please enter a number to be evaluated:",0dh,0ah,0
factor DWORD 2
hold DWORD ?
.code
main PROC
    call Clrscr  

    mov  edx,offset myMessage
    call WriteString            ;Displays myMessage
    call ReadDec                ;Puts value into EAX register
    mov edi, factor
    call prime


    exit
main ENDP

prime PROC

step1:  xor edx, edx
        div edi
        cmp edx, 1
        jz step2
        add factor, 1
        mov edi, factor
        jmp step1

step2:  mov hold, eax
        mov eax, edi
        call WriteDec
        mov eax, hold
        CMP eax, 1
        jz step3
        jmp step1

step3:  
        exit
prime ENDP


END main
4

1 に答える 1

1

あなたがやろうとしていることを私が理解しているなら、あなたはどのようにそしてどのようcmpjz働くかについて誤解していると思います。

cmp結果を保存せずに、宛先(最初)からソース(2番目)のオペランドを減算し、結果に基づいてフラグを設定することによって機能します。符号なし数値の場合、関連するフラグはキャリーとゼロです。ソースがデスティネーションよりも大きい場合、減算は最も高い位置から借用し、キャリーフラグを設定する結果になります。ソースと宛先が同じである場合、結果はゼロになり、ゼロフラグが設定されます。ソースがデスティネーションよりも小さい場合、減算によって0になったり、キャリーが発生したりすることはないため、両方のフラグは0になります。

jzおよびその他の条件付きジャンプ)は、フラグの現在の状態に応じてジャンプを実行します。具体的にjzは、ゼロフラグが設定されている場合にジャンプを実行します。cmpオペランドが等しいことを示すためにゼロフラグを設定するため、等しい場合のジャンプ()je命令は、実際にはジャンプがゼロの命令と同じです。キャリーの場合のジャンプ(jc)と以下の場合のジャンプ(jb)の指示も同じ理由で同じです。

cmpどのオペランドが大きいかを示すフラグを設定するため、命令jzが混乱する可能性があります。オペランドの1つがゼロの場合ではなく、オペランドが等しい場合にジャンプします。からあなたのコードを見てくださいstep1

div edi
cmp edx, 1
jz step2

step2除算の余りが0の場合はジャンプすることだと思いますが、cmp動作の都合上、余りが1の場合は実際にはstep2にジャンプします。修正は簡単です。1を0に変更します。 (注:ジャンプの理由をよりよく説明するために変更jzしました。前に述べたように、それらはまったく同じです。)je

div edi
cmp edx, 0
je step2

さらに、因子が見つからない場合、古い値を保持しません。たとえば、入力値が3の場合、step1ループは次のように機能します。

  1. 開始:eax= 3、edi= 2
  2. eaxで割りediます。商をeaxに、剰余をに格納しedxます。
    • ここで、eax= 3/2 = 1、およびedx= 3%2=1です。
  3. edx0ですか?その場合は、印刷ediしてループの最初に移動します。
    • そうではないので、続けてください。
  4. に1を追加しediます。今は3です。
  5. 新しい値eax=1およびedi=3を使用してステップ2を実行します。
    • さて、eax= 1/3 = 0、edx= 1%3 = 1
  6. ..。

因子が見つからなかったとしても、の値eaxが変更されていることに注意してください。あなたがする必要があるのはあなたが除算をする前にその価値を保存することです。これには変数を使用できます。holdこれは、因子が見つかるたびに変数がすでに更新されていることを意味します。ループを開始する前に値を保存し、各ループの開始時に値を復元するだけです。

        mov hold, eax
step1:  mov eax, hold
        xor edx, edx
        ...
于 2011-10-25T20:52:25.793 に答える