2017-11-25 11 views
0

MIPSを使用してDijkstraのアルゴリズムの実装でエッジ(ソースのインデックス|宛先のインデックス)を表す整数の配列を作成しようとしています。エラー#5:アラインされていないワードメモリ参照

rsimで実行しているときに、「アラインされていないワードメモリ参照」エラーが発生しています。私は、メモリアライメントが何を指しているのか誤解していると思います。私の.dataのは.textセクションでは

.data 
.align 4 

enterNode:   .asciiz "Enter the number of nodes: " 
enterEdges:   .asciiz "Enter the number of edges: " 
enterSource:  .asciiz "Enter source: " 
enterDestination: .asciiz "Enter destination: " 
enterWeight:  .asciiz "Enter weight: " 
newLine:   .asciiz "\n" 
min_nodes:   .word 1 
max_nodes:   .word 20 
error1:    .asciiz "Invalid number of nodes. Must be between 1 and 20.\n" 
error2:    .asciiz "Invalid number of edges. Must be between 0 and 400.\n" 
edgeArr:   .space 4800 
    # source | destination | weight 
input:    .space 5 

を下回っている、私は配列に入力するエッジの数のデータをループしていますが、私が参照したり、アドレスを計算しています方法が間違っているようです。

addi $t0, $zero, 0     # Edge counter 
la  $t1, edgeArr 
addi $t2, $zero, 0 

loop: 
    # Source 
    addi $v0, $zero, PRINT_STRING # Print user prompt 
    la  $a0, enterSource 
    syscall 
    addi $v0, $zero, READ_INT  # Take user input 
    syscall 
    add  $t3, $t2, $t2    # Calculate address in array 
    add  $t3, $t3, $t3 
    add  $t3, $t1, $t3 
    sw  $v0, ($t3) 
    addi $t2, $t2, 1 

    # ...destination and weight are effectively identical to source... 

    # Loop condition 
    addi $t0, $t0, 1 
    slt  $t4, $t0, $s1 
    bne  $t4, $zero, loop 

私はいくつかの同様の質問を見てきましたが、彼らは非常に私は誤解だ部分に対応していないようだ、と私は本当にこのを見て、目の新鮮なペアから利益を得ることができます。

答えて

2

.align 4.wordディレクティブの間に文字列があります。

.align 4現在の位置を4の倍数にするパッド。文字列の合計サイズは4の倍数ではないため、.wordディレクティブはワードアライメントされたメモリアドレスにありません。

.data 
.align 4 
min_nodes:   .word 1 
max_nodes:   .word 20 

edgeArr:   .space 4800 
    # source | destination | weight 
input:    .space 5    # 5 bytes?? 


enterNode:   .asciiz "Enter the number of nodes: " 
enterEdges:   .asciiz "Enter the number of edges: " 
enterSource:  .asciiz "Enter source: " 
enterDestination: .asciiz "Enter destination: " 
enterWeight:  .asciiz "Enter weight: " 
newLine:   .asciiz "\n" 
error1:    .asciiz "Invalid number of nodes. Must be between 1 and 20.\n" 
error2:    .asciiz "Invalid number of edges. Must be between 0 and 400.\n" 

min_nodesは、ビルド時の定数である場合は、代わりにすべてのメモリに格納する.equでそれを定義します。それ以外の場合はゼロに設定し、$t0 < min_nodes(符号なし)場合$t1=1を設定する

.equ min_nodes, 1 
.equ max_nodes, 20 

... 
li $t0, min_modes 

またはsltiu $t1, $t0, min_modesを(だから、すぐに定数として使用することができます)。大きな符号なしの値にラップする1以上

addui $t1, $t0, -1 
then compare against 19 (unsigned) 

値以下(及び19よりも大きい比較):そして、ところで、あなたは1つのブランチのみで範囲チェックを行うことができます。 20を超える値は、まだあなたはまた、読み書きの値を使用して文字列定数を混在させる必要はありません19.


より大きくなります。アセンブラが.rodataまたは.section .rodataをサポートしている場合、読み取り専用文字列は実行可能ファイルのテキストセグメントに入り、書き込み禁止になります。

+0

ありがとう、これは私が探していた正確な説明です。私は配列を宣言していた場所については考えていませんでした。また、最小ノードと最大ノードを必ず変更します。あなたは単純な定数であり、おそらくそれを宣言するより良い方法であるという点で正しいです。アセンブラが.rodataをサポートしているかどうかはわかりませんが、ドキュメントを調べます。ありがとうございました! – Gladdstone

関連する問題