2010-12-15 3 views
1

最初に、これは実際にはx86ではないことを指摘します。これは、学習目的でx86の簡略化されたバージョンであるmsx88です。質問に移るには、演算エラー(キャリー、オーバーフロー)をチェックする関数を作成する必要があります。チェックのためにjoとjcを使うことができますが、問題はチェックの後に戻ります(私はコールを使いたくないし、ジャンプがIPを格納しているかどうか分からないので、retを使うことができるかどうかわからない)。 JOを実行できるようにコードを変更するにはどうすればよいのですか?JO(JC)の後に次の命令に戻るようにジャンプする場合はどうすればいいですか?x86 ASMを扱う方法jc

ORG 3000H 
ArithmeticError: MOV AX, 0 
JO overflow 
JC carry 
RET ;Return 
overflow: ADD AX, 1 
carry: ADD AX, 2 


;If overflow AX=1, if carry AX=2, if overflow and carry AX=3, else AX=0 
ORG 2000H 
CALL ArithmeticError 

END 
+0

みんなありがとうようなものが、そのような迅速な応答を期待していなかった、と私はそれに取り組む前に、問題を考える方法についての事または2を学びました。 – Aviar

答えて

1

算術演算の前にフラグを保存する必要があります。あなたの応答のための

MOV AX,0 ; NB not XOR to keep flags intact! 
    JNO no_overflow 
    PUSHF ; save flags 
    INC AX 
    POPF ; restore them back for the second check 
no_overflow: 
    JNC no_carry 
    ADD AX,2 
no_carry: 
    ; if AX is zero, we have no error 
    TST AX 
    JZ out 
    CALL ArithmeticError 
out: 
    RET 
+0

msx88命令セットにはTSTが含まれていませんが、私はそのケースの否定を管理する方法が好きです.TSTを置き換える方法を試すことができます。 – Aviar

0

JMPは呼び出し元アドレスを保持しません。

CALLを実行したくない場合は、結果をどこかに保存し、他の処理を行い、呼び出しを行います(または現在のプロシージャ内で同じ機能を実行します)。

なぜコールを使用したくないのかはっきりしませんが、コール先の場所に戻る場合は、コールを使用するのが最適です。

+0

実際、私がやりたいことは、JNCをして呼び出しを行うことです。キャリーが設定されていれば、飛び越えずにコールします。そして、コールが戻った後、何も起こっていないかのように続けます。キャリーが設定されていない場合は、コールにジャンプします。 –

+0

JOがオーバーフローするとJCチェックが再び表示され、新しいチェックが失敗した場合には新しいJCチェックの後にRETが表示されるように単純に変更しました。新しいチェックが成功すると、キャリーにジャンプします。その場合、後でRETを追加してその機能を完了させるだけです。元のJOまたはJCのどちらもジャンプしない場合、単にAXに0を返します。 – Aviar

+0

ちょうどあなたがジョナサンを書いたことを読んで、学習のために、私はあなたの方法を試してみます。それはよりエレガントなようですが、もし私がそれを真っ直ぐに持っていれば、コールの前にJNCを追加してください。エレガントなアイデア。 – Aviar

0

コールを使用したくない場合は、変更したIPをスタックにプッシュし、JMPを使用してからRETを使用できます。以下は擬似コードです。

PUSH [IP] +x ; [where x is the size which would evaluate to instruction just after POP IP] 
JO OVERFLOW 
ADD SP, y ; y is size of address. if jump was not taken 
XOR EAX,EAX ;the IP of this instruction minus orginal IP would be x 


OVERFLOW: 
; program instructions 
RET 
関連する問題