3

私は「jmp out of range」というエラーに苦労してきました.C++で関数を実行するように、コードのさまざまな部分からサブルーチンを実行する必要があることがよくあります。

コードの両端が同じ場所にジャンプする必要があるという点に到達しましたが、両方がそこに到達する方法はありません。

これに対する解決策は何ですか?

また、私はそれに気づきました

PRINT 'something'

使用するよりも多くの「スペース」を占有しているようです:

CALL PTHIS
DB 13, 10, 'something', 0

(2 つのジャンプの間に PRINT を配置すると範囲外にジャンプしますが、PTHIS に置き換えれば問題ありません)

どうしてこれなの?

4

2 に答える 2

5

16 ビット アセンブラーの条件付きジャンプ命令の問題は、オフセットが +127 または -128 バイトに制限されていることです。

386 では、jcc rel1616 ビット モードで使用できるエンコーディングが導入されましたが、386 以降でのみ使用できます。アセンブラが異なれば、16 ビット コードで 386 命令を有効にするためのオプションも異なります。

jcc rel8一部には、以下で説明することを自動的に実行するオプションもありますjmp rel16。たとえば、TASM には/jJUMPS.


あなたがこれを持っているとしましょう:

    cmp al, '1'
    jnz ItsNot1
    ; lots of code here
ItsNot1:

範囲外のエラーが発生した場合は、次のように再コーディングできます。

    cmp al, '1'
    jz Its1
    jmp ItsNot1
Its1:
    ; lots of code here
ItsNot1:

私が行ったのは、比較の意味を変更し、別のコード パスに移動する無条件ジャンプを回避することだけです。

条件付きジャンプがたくさんあると、面倒になることがあります。それらの1つを再コーディングすると、別のトリガーがトリガーされます。そして、コードをリファクタリングし、それらの壊れた条件の一部がなくなる可能性があることを発見します。通常、コード サイズを真剣に気にしない限り、気にすることはありません。

一部のアセンブラには、自動ジャンプ サイズ設定を行うスイッチがあり、いつでも条件付きジャンプをコーディングでき、ジャンプ アラウンド条件付きジャンプ トリックを自動的に実行できます。

ほとんどの場合、

PRINT 'something'

call PTHIS
db 13, 10, 'something'

最初のものは、何かを印刷するための完全なコードに加えて、印刷したい文字列に展開されるマクロです。2 番目は単純なcall命令 (3 バイト) と文字列です。または、C++ の用語では、PRINTマクロはインライン関数のようなものでcall PTHIS、通常の (インライン化されていない) 関数呼び出しです。

于 2013-06-25T21:37:15.497 に答える
0

フォールスルーが範囲外の目的地への無条件のジャンプである間に、テストを無効にしてブランチを少し先にジャンプさせる必要がある場合があります。

于 2013-06-25T21:36:21.767 に答える