1

私は Y86 を学ぼうとしているので、とても簡単なプログラムを作りました。これには 3 つの long 整数の配列があり、各ブロックは を介し​​てユーザーに入力を求めることで埋められますrdint

コンパイルされた (?) プログラムは 3 つの入力を要求しますが、それらを出力することはできません。

コード:

Main:   irmovl  Array, %edx
rdint   %eax
rmmovl  %eax, 0(%edx)
rdint   %eax
rmmovl  %eax, 4(%edx)
rdint   %eax
rmmovl  %eax, 8(%edx)

irmovl  $10, %edi
Print:  irmovl  Array, %edx
    mrmovl  0(%edx), %eax
    wrch    %eax
    wrch    %edi
    mrmovl  4(%edx), %eax
    wrch    %eax
    wrch    %edi
    mrmovl  8(%edx), %eax
    wrch    %eax
    wrch    %edi

    halt

    .align 4

Array:
    .long 0
    .long 0
    .long 0

私の入力:

0
1
2

出力:

(three blank lines below)



Stopped in 22 steps at PC = 0x47.  Exception 'HLT', CC Z=1 S=0 O=0
Changes to registers:
%edx:   0x00000000      0x0000004c
%edi:   0x00000000      0x0000000a

Changes to memory:
0x0004: 0x024008f2      0x00000001
0x0008: 0x00000000      0x00000002

Changes to memory: 0x0004: 0x024008f2      0x00000001 0x0008:
0x00000000      0x00000002
4

1 に答える 1

0

このプログラムには古典的な問題があります: ys ファイルに改行がないため、YAS が誤動作します。

最初の問題は、YAS のエラーによるものです。YAS によって作成された yo ファイルを見ると、最後の .long 0 ステートメントが定義されていないことがわかります。おそらく、yo ファイルの最初の行のオペコードが 0x00、つまり nop であることもわかるでしょう (関連する改行のない最終命令に YAS が遭遇すると、YAS はそれをラップして yo ファイルを台無しにします)。

これは、最初の irmovl 配列 %edx を失うことを意味し (これはある種のナンセンス、おそらく 0x00000000、つまり 4 つの nops になります)、最初の読み取り文字 x'30' ('0' の ascii) をその場所に書き込みます。 edx が指す (おそらく 0x00000000) は最初の命令にあります (これは 4 つの nops でした。文字を読み取ったことを思い出してください。ただし、最終的には 4 バイトのレジスタに格納され、そのように保存されます)。 0x00000000 から 0x00000000 だったアドレスは、YIS にとってレジスタが変更されなかったことを意味するため、「Changes to Memory」ダンプ セクションには表示されません。

2 番目の読み取りでこれを繰り返し、2 番目のワードに 0x00000001 を書き込み (その場所の命令を上書き)、3 番目の読み取りで 3 番目のワードに 0x00000002 を書き込みます (その場所の命令を上書きします)。

もちろん、あなたは完全にうんざりしています!(edxを使用して)配列へのポインターをリセットし、コンテンツを印刷しようとしましたが、Array(0)、Array(4)、およびArray(8)には0x00000000が含まれています。これは、(. Y86 の未定義メモリのデフォルト設定は 0x00000000 であるため、Array(0) と Array(4) には long 4 ステートメント、Array(8) には自動的に 4 ステートメントを使用します。したがって、プログラムは x'00' を出力します (1 文字を出力するため)。もちろん、ジャンクです。

これは YIS からのダンプと一致することに注意してください。eax は、初期値の 0x00000000 から変更されていないため表示されません。edx と edi は問題ないように見えますが、edi は Array(8) を指しています。変更された唯一のメモリは、プログラムの 2 番目と 3 番目のワードです (それぞれ 0x00000001 と 0x00000002 で上書きされています)。

ということで、まとめ。YASは間違いを犯します。最後の .long 0 ステートメントの後に改行を追加して、この問題を解決する必要があります。YIS は、コードをデータで上書きしても例外をスローしないため、誤解を招きます。

于 2012-11-08T04:00:30.177 に答える