0

.word のインデックスにアクセスできません。その場合はできますがlist: .word 1, 2, 3, 4list: .word 0x12345678「フェッチアドレスがワード境界に整列していません」というエラーが表示されます。これが私のコードです:

.data
list: .word 0x12345678
outbuff: .space 40
.text
la $t3, list
la $t5, outbuff
li $t2, 3
add $t5, $t2, $t3
lw $t4, 0($t5)
jr $ra

リストの特定のインデックスにアクセスできない理由がわかりません。私の最終目標は、上記のように 16 進数を取り、そのバイナリ表現を出力することです。lis の特定のインデックスにアクセスする方法を理解するのを手伝っていただければ幸いです。ありがとうございました。

編集:

.data
list: .word 0x12345678
outbuff: .space 40
.text
la $t3, list
la $t5, outbuff

li $t1, 0
loop:
    addi $t1, $t1, 1
    beq $t1, 32, end
    la $t2, ($t3)
    #addi $t2, $t2, 2
    lb $t4, 0($t2)
    and $t5, $t4, $t1
    sll $t2, $t2, 1
    j loop
end:
4

2 に答える 2

2

MIPS では、ワード境界に整列していないアドレスからワードをロードすることはできません。それがCPUの限界です。

あなたの場合、t5のアドレスは整列されていません-list整列されていますが、それに3を追加します。その3が何のためにあるのかわかりません。バイトごとに処理したい場合は、次のことができます。しかし、その後は使用しないでくださいlw。とにかく、それは非常に最適ではありません。

バイナリ表現を書き出す場合は、ワードをロードし、listシフトおよび AND 演算を使用してビットを 1 つずつ抽出します。

編集: コンパイルされたコードで数値の 16 進表現が存続すると仮定するのは誤りです。コンパイルされたコードでは、取得できるのはバイナリだけです。でワードをロードするlistと、値 0x12345678 (16 進数) の整数がレジスタに取得されます。これは、305419896 (10 進数) または 10010001101000101011001111000 (2 進数) と同じです。

とにかく、当面のタスクはバイナリ文字列を作成することです。割り当ては、出力に先行ゼロを含めるかどうかをカバーする必要があります。先行ゼロは問題ないと仮定しましょう。これにより、ロジックが簡単になります。

整数は、一連のビットとして内部的に格納されます。各ビットを左から右に取り、それを ASCII 数字 (「0」または「1」) に変換します。

数値から単一のビットを取得するには、このビットのみを含む定数 (別名マスク) を使用してビットごとの AND 演算を実行する必要があります。つまり、0 番目のビットを確認するには 1 と AND し、31 番目のビットを確認するには 0x80000000 と AND します。演算の結果が 0 の場合、ビットは最初からゼロでした。結果がゼロ以外の場合 (実際、マスク自体と等しい場合)、ビットは 1 でした。

もう 1 つのヘルパーは、シフト操作です。ビットをループできます。ビットを左から右に綴りたいので、一番左のビットをチェックして左にシフトします。

要約すると、単語をレジスタにロードします。32 回の反復のループを作成します。繰り返しごとに、マスク 0x80000000 のビットの値を確認します。その値に応じて、'0' または '1' を出力配列に書き込みます。

これをさらに詳しく説明する必要がありますか、それともそのようなアルゴリズムを MIPS アセンブリに変換できますか?

re:code を編集します。

ループの反復ごとに変数をロードする必要はありません。ループの前に一度ロードします。あなたがそれをシフトしているので、そうでなければうまくいきません。t2 の初期値は 0x12345678 ですが、ビットを 1 つずつ処理し始めます。値をリロードすると、それが台無しになります。

lb無意味です。あなたはすでにあなたの言葉を記憶しています。

出力配列への条件付き書き込みはありません。AND を実行しますが、まったく奇妙な方法です。ところで、あなたの AND コマンドでは、t5 の値を台無しにしています。そして、あなたはその AND からフォローアップしません。出力配列にバイトを格納し、そのバイトの値が AND の結果に依存する何らかのロジックが必要です。

そして、あなたはまだ何listを表しているのか混乱していると思います. メモリ内の配列ではありません。これは 4 バイトで、別名 1 つの 32 ビット ワードです。のバイトをループする必要はありませんlist。ビットをループする必要があります。

全体の混乱は、変数「リスト」を呼び出すことから始まりました。非常に誤解を招く名前です。変数は何かのコレクションではなく、スカラー、32 ビット整数です。

于 2014-03-19T19:31:42.990 に答える
1

32 ビット ワードの個々のバイトにアクセスする必要がある場合は、LB(load byte) 命令を使用する必要があります。

la   $t3, list
la   $t5, outbuff
li   $t2, 3
addu $t5, $t2, $t3
lb   $t4, 0($t5)

(LWロード ワード) 命令では、アドレスが 4 バイトのワード境界に揃えられている必要があります。

于 2014-03-19T19:35:31.603 に答える