1

というわけで、組み立てをいじっていたら、変なものを見つけました。何かを書き込む前に、レジスタを次の値に設定します。

AX 0000, BX 0000, SP 00FD.

レジスタ AX と BX を増やす単純なコードを書いたとしましょう。

A100
INC AX
CALL 0200

A200
INC BX
RETN

書いた後、Tコマンドを使ってコマンドを1つずつ実行するとレジスタがどのように変化するかを調べてみました。1回目は を増やしAXて に移動し0200、 を増やしBXて戻ります。奇妙な点は次のとおりです。返されると、 command: が実行 され、再度ADD [BX+SI],AX呼び出さ0200れます。

再度呼び出す0200と、それ自体が繰り返されますが、現在、返されると、CALL 0100コマンドに戻り ( にではなく)、再びCALL 0200増加します。AXなぜこうなった?

私は完全な出力の画像を持っています.これは私の質問をよりよく理解するのに役立つでしょうか?: http://s18.postimg.org/wt6eracg9/Untitled.png

4

2 に答える 2

3

スクリーンショットに基づいて、コードは次のようです ( で埋められnop、 で逆アセンブルされていudcliます):

エコー 40 e8 fc 00 01 00 e8 f7 00 e8 f4 ff x{1..244} 43 c3 | sed 's/x[0-9]*\>/90/g' | udcli -o 0x100 -x -16
0000000000000100 40インチ斧
0000000000000101 e8fc00 コールワード 0x200
0000000000000104 0100 add [bx+si], ax
0000000000000106 e8f700 コールワード 0x200
0000000000000109 e8f4ff コールワード 0x100
000000000000010c *** 到達していません ***

0000000000000200 43インクbx                  
0000000000000201 c3 ret                     

コード フローは次のとおりです。

0000000000000100 40インチ斧

axインクリメントされます。

0000000000000101 e8fc00 コールワード 0x200

戻りアドレス 0x104 がスタックにプッシュされ、ip(命令ポインタ) が 0x200 に設定されます。

0000000000000200 43インクbx

bxインクリメントされます。

0000000000000201 c3 ret

つまり、ipスタックからポップされます。新規ipは 0x104 になります。

0000000000000104 0100 add [bx+si], ax

の値がax単語値 at に追加され[bx+si]ます。

0000000000000106 e8f700 コールワード 0x200

戻りアドレス 0x109 がスタックにプッシュされ、ip(命令ポインタ) が 0x200 に設定されます。

0000000000000200 43インクbx

bxインクリメントされます。

0000000000000201 c3 ret

つまり、ipスタックからポップされます。新規ipは 0x109 になります。

0000000000000109 e8f4ff コールワード 0x100

戻りアドレス 0x10c がスタックにプッシュされ、ip(命令ポインタ) が 0x100 に設定されます。したがって、これは実際には無限再帰関数であり、スタックが不足します。

したがって、問題は、 の後にコードを定義しないことですCALL 0200。たまたま01 00( add [bx+si], ax) があり、return 後に実行され、その後に他の未定義命令が実行されます。

私のアドバイス: まともなアセンブラ (NASM、YASM、FASM...) をできるだけ早くダウンロードし、DEBUG でアセンブリ コードを書こうとして人生を台無しにしないでください。DEBUG を使用してアセンブリ プログラムを作成しようとすると、失敗する運命にあります。

于 2013-11-10T11:44:03.517 に答える