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

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

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

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

Q&A

解決済

3回答

2177閲覧

乗算を行ったとき下位レジスタに入り切らないときの出力

yomoanyan

総合スコア14

アセンブリ言語

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

0グッド

0クリップ

投稿2021/05/29 01:51

編集2021/06/01 00:59

前提・実現したいこと

アセンブリ言語でmult命令を使った際、上位32bitはHIレジスタに、下位32bitはLOレジスタに入ると教わったのですが、HIレジスタまで使う数が計算結果となった場合、どのようにしてHIレジスタとLOレジスタ内の値を繋ぎ合わせ値を出力すれば良いのでしょうか?

例えばですが、キーボード入力をxとして100*xを計算し表示するというプログラムはこんな感じでいけると思いますが、これだとLOレジスタ内ですむ計算しかできません。

どのようにすればHIレジスタまで使う計算結果も出力できるのでしょうか?

CPUはMIPS、処理系はSPIMです。バージョンは申し訳ないですが、分かりません

よろしくお願いします。

.data newln: .asciiz "\n" .text .globl main main: addi $sp, $sp, -4 sw $ra, 0($sp) move $t0, $zero # t0を0に初期化 li $v0, 5 syscall # 数を聞き、読み取る。これをxとした li $t1, 100 # t1に100を入れる mult $t1, $v0 # 100 * x mflo $t0 # LOレジスタからt0に値を持ってくる move $a0, $t0 li $v0, 1 #値の出力 syscall la $a0, newln # 以下改行命令 li $v0, 4 syscall lw $ra, 0($sp) # 戻り先アドレスの復元 addi $sp, $sp, 4 # スタック領域の開放 jr $ra # プログラムの終了

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

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

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

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

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

dameo

2021/05/30 15:56

CPUはMIPSで、処理系はMARSですか? お手数ですが、まずはその情報をご記載ください。
yomoanyan

2021/05/30 23:22

CPUはMIPSで、SPIMですね。
dameo

2021/05/30 23:28

あ、お手数ですが、質問文にご記載ください。バージョンなども分かればお願いします。
yomoanyan

2021/05/30 23:35

書きました。バージョンは申し訳ないですが、大学から用意された環境で行っているのでいまいちよく分かりません。確認方法なども調べたのですが、調べ方が悪いのかわからなかったので、よろしければ教えて欲しいです。
dodox86

2021/05/30 23:43

SPIM(実行環境)であれば、対象としているCPUの種別はR2000かR3000のはずです。最新のQtSpimかそれより前のものか。QtSpimなら、ウィンドウメニューの「Help」からバージョン確認できますね。
dameo

2021/05/30 23:44

ubuntuにaptで入れただけですが、 $ spim SPIM Version 8.0 of January 8, 2010 Copyright 1990-2010, James R. Larus. All Rights Reserved. ... お使いのものと同じか分かりませんが、こんな感じに出るみたいです。 この表示だと8.0みたいですね。
dodox86

2021/05/30 23:53 編集

参考: ちなみにWindows版のQtSpimのバージョン情報を覗くと、 Version 9.1.21 of January 17,2020 SPIM is a simulator of the MIPS R3000 processor.. Copyright(c) 1990-2015, James R. Larus ...省略 と出ました。R3000のみサポート、なのだと思います。
dameo

2021/05/31 19:41

とりあえず、R2000でも動くSPIMで、0~255までの数字を入力してもらってシステムコール4(文字列出力)だけで入力された整数を出力するコードを適当に書いてみました。ご参考までに。     .data newln: .asciiz "\n" result: .space 4     .text     .globl main main:  addi  $sp, $sp, -4     sw   $ra, 0($sp)     move  $t0, $zero   # t0を0に初期化     li   $v0, 5          syscall         # 数を聞き、読み取る。(0〜255までの8bitとする)     move  $t0, $v0    # t0に入れる。割られる数     la   $t4, result + 3     sb   $zero, ($t4)   # NUL文字をストア print_loop:     sub  $t4, $t4, 1   # 次の位置へ移動     li   $t1, 160    # t1(筆算で引く数)に160を入れる     li   $t2, 16     # t2(商に足す数)に16を入れる     move  $t3, $zero   # t3(商)を0に初期化     # 2進数で10で割る筆算 div_loop:     blt   $t0, $t1, cannot_sub     # 筆算で1が立つケース     sub   $t0, $t0, $t1  # 余りの計算(1bit分)     or   $t3, $t3, $t2  # 商の計算(1bit分) cannot_sub:     # 筆算で0になるケース     srl   $t1, $t1, 1     srl   $t2, $t2, 1     bne   $t2, 0, div_loop     add  $t0, $t0, 48   # 余り1桁をASCIIコードに変換     sb   $t0, ($t4)    # 1文字ストア     move  $t0, $t3     # 商を割られる数に設定     bne  $t0, 0, print_loop     # 結果の表示     move  $a0, $t4     li   $v0, 4     syscall     la   $a0, newln   # 以下改行命令     li   $v0, 4     syscall # 半角空白2つを全角空白に変換しています
dameo

2021/05/31 19:47

言い忘れました。 64bitの割り算は自力で計算する必要があるため、乗除算を使用せず、2進数の筆算を念頭に書いています。
yomoanyan

2021/06/01 01:03 編集

@deameoさん ありがとうございます。参考にさせていただきます。BAにしたいので適当に回答を残していただきたいです。
dameo

2021/06/01 01:01

いえいえ、多分yomoanyanさんが64bitの整数表示コードを書いたときこの問題は初めて解決すると思います。 無理に解決する必要はないですけど、その機会を奪いたくはないので、このままにさせてください。
yomoanyan

2021/06/01 01:04

分かりました。ちょっと今はまだ難しいかもしれないですけど、もう少し勉強したらまたやってみたいと思います。
guest

回答3

0

ベストアンサー

アセンブリ言語で

一般的に、アセンブリ言語の仕様はCPUごとに全く違うので、ただ「アセンブリ言語で」と言ってもどのCPUの話か分かりません。明記してください。
今回の場合MIPSであることまではわかりますが、バージョンも分かりませんし(hi/loでやや古いのは分かるが)、syscallで呼び出されているシステムコールの仕様も分かりません。

どのようにすればHIレジスタまで使う計算結果も出力できるのでしょうか?

まずそういうプログラムどこかにがあるか探して、
無ければ自分で順を追って頑張ってプログラムを書くか、諦めてください。

状況から判断するに、1つのレジスタだけの結果を出力する方法をあなたは知らないものと思います。
誰かが頑張って書いた「1つのレジスタの内容を出力するプログラム」をsyscallを通して使っているだけです。
同様に「2つのレジスタの内容を出力するプログラム」を誰かが作ってくれていればよいですが、見つからなければ苦労して書くことになります。
1文字出力はシステムコールを使うとして、まずは加減乗除論理演算シフトあたりを駆使して1つのレジスタの内容を出力するプログラムを書いてから、複数ワードに渡る値の加減算・乗算あたりを理解して、2つのレジスタの値の出力という順になるかなと思います。
10進↔2進変換は色々な手法があり奥の深い題材です。とりあえず計算が素直な「shift and add 3」法を調べてみるとよいでしょう。

なお、MIPSは複数ワードに渡る値を扱うのがキャリーフラグを使う他のCPUと比べ面倒です。

単に出力が見たいだけなら諦めて上下を別々に表示してPC側でどうにかするのが楽です。

投稿2021/05/30 07:00

ikadzuchi

総合スコア3047

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

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

yomoanyan

2021/05/30 08:09

回答ありがとうございます。 自大学の資料は外部に出せない決まりなので他大学の資料になってしまうのですが、システムコールの仕様はこれと同じような感じだと思います。 http://www.cc.kyoto-su.ac.jp/~kbys/kiso/cpu/mips3.html バージョンですが、大学で用意された環境でやっているの分かりません。 つい最近習い始めたばかりで、なんとなく疑問に思ったことを軽い気持ちで投稿したら思ったよりややこしい問題だったようで驚いてます。とりあえず「shift and add 3」法を調べてみます。 ありがとうございます。
guest

0

HIレジスタ<<32|LOレジスタ で、64ビットの結果が得られます

投稿2021/05/29 05:28

y_waiwai

総合スコア87774

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

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

yomoanyan

2021/05/29 14:43

回答ありがとうございます。 HIレジスタを32ビット左にシフトするという意味でしょうか?
y_waiwai

2021/05/30 06:39

対象としてるCPUが不明なのでこういう記述になってしまいましたが、 そういう意味です
guest

0

2つのレジスタを連結した数値を10進数で表示したいと言うことですかね?

syscallの機能が分かりませんが、丁度ぴったりの機能が無いのであれば、
自分で10進表現に変換するコードを書いて1文字ずつ文字として表示するのでしょう。

HI LO を連結した値に対しての割り算機能はあるのでは?

投稿2021/05/29 02:30

otn

総合スコア84557

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

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

yomoanyan

2021/05/29 14:47

回答ありがとうございます。 2つのレジスタの連結した数値を10進数で表示したいと言うことですかね? >そうです。言い方が分かりにくくてすみません。 一つずつ計算していくと言う方法を試してみたいと思います。 連結した値に対しての割り算機能は調べてみたのですが、分かりませんでした。
otn

2021/05/29 14:51

割り算命令は存在するのでしょうか?
yomoanyan

2021/05/30 00:16

div $rs, $rt でrs/rtがLOレジスタにrs%rtがHIレジスタに入ると言う命令はあります。
pepperleaf

2021/05/30 00:47

CPUが分からないですが、BCD演算は無い? あれば、それを使えば。
otn

2021/05/30 09:35

命令にないとすると、その代用相当を自分で作らないといけないので、ちょっと荷が重いのでは?
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問