2016-05-26 5 views
0

2つの入力を取り込むプログラムを作成しようとしていますが、それらをレジスタに格納してからデータセグメントに格納します。データセグメントにレジスタ値を格納しようとするとMIPSの実行時例外が発生する

.data 
val1: .word 1 
val2: .word 2 
val3: .word 3 

.asciiz "Branden" 
.asciiz "Enter a number " 
.asciiz "\n" 

.globl main 
.text 

main: 

addi $s0, $0, 23 # initializes the register $s0 to 23 

lui $a0, 0x1001 
ori $a0, $a0, 20 #outputs string that is at 20 
ori $v0, $0, 4 #command for output 
syscall 
addi $v0, $0, 5 # asks for input 
syscall 
addi $s1, $v0, 0 # set the value of $s1 as the given input 


lui $a0, 0x1001 
ori $a0, $a0, 20 #outputs string that is at 20 
ori $v0, $0, 4 #command for output 
syscall 
addi $v0, $0, 5 #asks for input 
syscall 
addi $s2, $v0, 0 # set the value of $s2 as the given input 

sw $s1, 0($t0) # store the value of $s1 into data segment val1 
sw $s2, 4($t0) # store the value of $s2 into data segment val2 


ori $v0, $0, 10 
syscall 

問題は、私はこのエラーを取得しています:Cでエラー:0x0040003cでのランタイム例外:範囲外のアドレス0x00000000の

\ユーザーは、ダニー\ MIPS \のassignment1.asmライン34を\どのような理由でsw $ s1、0($ t0)行にエラーが発生していますか? swと関連付けられたlwが必要ですか?

+0

クラッシュ時にt0レジスタには何が入っていますか?私はあなたがそれを設定しているとは思わない、おそらく0?おそらく正しい答えではないでしょう。 –

+0

val1に格納する正しい形式は何ですか? $ t0にval1を格納するのにlwを使うべきですか? @DavidWohlferd – brandenfam

+0

あなたは 'lui、ori'の束をやっていることに気付きました。擬似操作(例: 'la'、' li')を使用できますか?また、 '.asciiz'文字列のオフセットをハードワイヤリングしています。それぞれには独自のラベルが必要です。例えば、 '.asciiz" Brandenを '' .asciiz "brandenfam" 'に変更すると、あなたのプリント文字列syscallが壊れます。 –

答えて

1

ダビデは、あなたはどのようにアドレスを得るでしょう、あなたは構文を使用したい場合でも、それsw

ためゼロだったので、何にでも$t0を設定しかしなかったが、前述のように? laはこれを簡単にします。

私は[無償スタイルのクリーンアップをご容赦ください]バグを修正し、生活を楽にするいくつかの擬似オペレーションを使用するように再コードしました:

.data 
val1:  .word  1 
val2:  .word  2 
val3:  .word  3 

me:  .asciiz  "Branden" 
enter: .asciiz  "Enter a number " 
nl:  .asciiz  "\n" 

    .globl main 
    .text 

main: 
    li  $s0,23     # initializes the register $s0 to 23 

    la  $a0,enter    # address of string to output 
    li  $v0,4     # print string syscall number 
    syscall 

    li  $v0,5     # asks for input 
    syscall 
    move $s1,$v0     # set the value of $s1 as the given input 

    la  $a0,enter    # address of string to output 
    li  $v0,4     # print string syscall number 
    syscall 

    li  $v0,5     # asks for input 
    syscall 
    move $s2,$v0     # set the value of $s2 as the given input 

    sw  $s1,val1    # store the value of $s1 into val1 
    sw  $s2,val2    # store the value of $s2 into val2 

    li  $v0,10 
    syscall 

    # NOTE: these are alternate ways to do the stores (they're after the exit 
    # so they won't be executed) 
    la  $t0,val1    # address of val1 
    sw  $s1,0($t0)    # store the value of $s1 into val1 

    la  $t0,val2    # address of val2 
    sw  $s2,0($t0)    # store the value of $s1 into val2 

UPDATE:

I am not allowed to use la or li but I did not know that I could directly use val1 with sw so that is helpful, thank you!

私は意図的に1つのフォームを表示しました。

しかし、swをこのように使用すると、実際には擬似的な処理になります。シーケンスを見ると、swlui $at,...を生成し、次にsw $s1,0($at)を生成することがわかります。

擬似操作については、基本命令では実行できないことがあります。緩く[いくつかのCのような構文を使用して]、la $t0,val1だからlui $at,(&val1 >> 16)、その後ori $at,$at,(&val1 & 0xFFFF)

を生成し、あなたは手でlaをコーディングすることができるかもしれません。しかし、[AFAIK]では、擬似的な操作ができるように、シンボルの "上/下"を指定/分割する方法はありません。

+0

私はlaまたはliを使用することはできませんが、私はswで直接val1を使用できることを知りませんでした。 – brandenfam

関連する問題