質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
アセンブリ言語

アセンブリ言語とは、機械語を人間にわかりやすい形で記述した低水準言語です。

Q&A

解決済

1回答

1305閲覧

MIPSで数字の配列を逆にする問題、で最初から二つ目の数字だけがエラーを起こす

aoba-purines

総合スコア13

アセンブリ言語

アセンブリ言語とは、機械語を人間にわかりやすい形で記述した低水準言語です。

0グッド

0クリップ

投稿2022/07/05 02:35

次の課題について質問があります。

入力された複数の整数値を入力と逆順に出力するプログラムをサブルーチンを用いずに作成せよ。このとき、最大値および最小値を出力する際はそれぞれ "(max)"、"(min)" の注釈を合わせて出力すること。入力の終端は0の入力で表すものとする(0は入力値とは見なさない)。入力値の個数は不明であり、必要に応じてスタック上に領域を確保して記憶すること。少なくとも1つ以上の有効な入力値があると仮定してよい(最初の入力が0であることに配慮する必要はない)。
あらかじめN(N>0)個分のデータ領域を確保するような実装はN+1個目の入力に対応できないので不適切なプログラムである。
(1)入力が1つの場合、(2)入力が2つの場合、(3)入力が十分多数の場合、いずれの場合も正しく動作すること。
入力の1つが最大値かつ最小値の場合、複数の入力が最大値かつ最小値の場合、"(max)"と"(min)"の注釈を併記すること。

これに対し、以下のプログラムを作成して実行しました。

.data nl: .asciiz "\n" max:.asciiz "(max)" min:.asciiz "(min)" .text .globl main main: addi $sp, $sp, -8 sw $ra, 0($sp) addi $t0, $sp, 4 li $t1, 1 li $v0, 5 syscall move $t2, $v0 move $t3, $v0 sb $v0, 0($t0) loop: li $v0, 5 syscall beq $v0, $zero, return addi $sp, $sp, -4 addi $t0, $sp, 4 addi $t1, $t1, 1 sb $v0, 0($t0) bgt $v0, $t2, remax ble $v0, $t3, remin j loop remax: move $t2, $v0 ble $v0, $t3, remin j loop remin: move $t3, $v0 j loop return: lw $a0, 0($t0) li $v0, 1 syscall beq $a0, $t2, MAX beq $a0, $t3, MIN la $a0, nl li $v0, 4 syscall cont: addi $t1, $t1, -1 beq $zero, $t1, end addi $sp, $sp, 4 addi $t0, $sp, 4 j return MAX: move $t4, $a0 la $a0, max li $v0, 4 syscall beq $t4, $t3, MIN la $a0, nl syscall j cont MIN: la $a0, min li $v0, 4 syscall la $a0, nl syscall j cont end: lw $ra, 0($sp) addi $sp, $sp, 8 jr $ra

しかし読み込ませた二つ目の数字だけがおかしくなってしまいます。

(spim) run 1 0 1(max)(min) (spim) run 1 2 0 4194306 1(min) Exception occurred at PC=0x00400000 Bad address in text read: 0x00400002 Exception 6 [Bad instruction address] occurred and ignored (spim) run 1 2 3 4 5 0 5(max) 4 3 4194306 1(min) Exception occurred at PC=0x00400000 Bad address in text read: 0x00400002 Exception 6 [Bad instruction address] occurred and ignored

こうなってしまう原因をわかる人がいらっしゃれば、どうか教えてください。よろしくお願いします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

main に入ってきたときのスタックポインタの値を initial_sp だとすると、

  • initial_sp - 8 には $ra が入る
  • initial_sp - 4 には最初に入力した値が入る

loop を一度通ると、

  • sb $v0, 0($t0) により initial_sp - 8 に2つ目に入力した値(8ビット)が入る。initial_sp-7 〜 initial_sp-5 は $ra の残骸

return に入ると

  • lw $a0, 0($t0)$a0 に inital_sp - 8 から32ビットの値が入る。

というわけで、

  • 値を書くサイズと読むサイズが一致していないこと
  • $ra を保存した領域を壊していること

が原因です。

投稿2022/07/05 03:05

編集2022/07/05 03:10
int32_t

総合スコア20832

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問