2016-07-20 13 views
0

私はアセンブリのコーディングが初めてで、次のCコードをMIPSアセンブリに転送するという問題に遭遇しました。CからMIPSへのアセンブリの混乱

b[8] = b[i-j] + x ; 

及び変数はI、J、Xは、レジスタ7,4及び15であり、配列bのベースアドレスは2870220小数です。

私は、次の解決策

lui $2, 0x002B 
ori $2, $2, 0xCBCC 
sub $3, $7, $4 
add $3, $2, $3 
lw $12, 0($3) 
addu $12, $12, $15 
sw $12, 32($2) 

を思い付いたが、私は答えをチェックすると、減算命令の後

sll $3, $3, 2 

の一つの追加の行がありました。

誰かが$ 3の内容に4を掛けなければならない理由を説明してください。

+0

配列はワードサイズ(32ビット)で、バイトサイズではありませんか? –

+0

問題は配列について何も指定しません。 –

+1

それはおそらくワードサイズです。実際に私はmipsの構文を忘れています、lwはロード・ワード・イエスですか? 32ビットのもの?ロードバイトは何ですか?ポンド? lwが32ビットの場合は、オフセットを1ワードに合わせる必要があります。したがって、4を掛けてアドレスにオフセットを取得してください。 –

答えて

0

私はイラストを与えます。

のは、我々はメモリ位置0x00000004に0x00000000の中に保存されたこれらの5バイト(例として、私は、メモリ・マップを無視しています)があるとしましょう:

を| 0x27 | 0x82 | 0x97 | 0x42 | 0x11 |

メモリアドレス0x00000000にワードをロードすると、ベースアドレスから次の4バイトが連結されるため、32ビットワード0x27829742が得られます。

ただし、メモリアドレス0x00000001では0x82974211になります。


私は、この誤解は演算子[]が配列でどのように実装されているのかと考えているので、私はそれを拡張しようとします。 ARRにアクセスする場合、[2]、それは考慮配列の要素のサイズを取る有する

int arr[3] = { 1, 3, 5 }; 
printf("%d\n", arr[2]); // print third element 

:以下のCコードを考えます。 int型の標準は、32ビット(4バイト)であると仮定すると、あなたはコンパイル時に以下のコードを得るでしょう。この場合

int arr[3] = { 1, 3, 5 }; 
printf("%d\n", *(arr + (2 * sizeof(int)))); // print third element 

を、それが指数を乗じたバイトの整数の価値によって、アレイのベースポインタをオフセットアクセスされた後、指定された要素を取得するためにdeferencedされます。結論として

メモリブロックは、8ビットバイト、32ビットではない言葉に並んでいます。

+0

最後のポイントを示す良い方法:メモリアドレスはバイトを参照します。全体の32ビットワード。したがって、隣接する2つの単語のアドレスは4で異なっています。また、Cのバージョンをどのようにしてコンパイルするのか知っていますが、表示されているコードは有効なCで、たぶん、 '((char *)arr)+ 2 * sizeof(int)'から4バイトの単語をロードするといいでしょう。 –