teratail header banner
teratail header banner
質問するログイン新規登録

質問編集履歴

1

必要な部分だけにしました。

2021/06/29 12:58

投稿

yomoanyan
yomoanyan

スコア14

title CHANGED
@@ -1,1 +1,1 @@
1
- MIPSアセンブリ言語を使ったコンビネーション計算
1
+ MIPSアセンブリ言語の階乗
body CHANGED
@@ -1,8 +1,6 @@
1
1
  ### 前提・実現したいこと
2
2
 
3
- MIPSのアセンブリ言語使ってコンビネーション(nCr)の計算を行うプログラムを作成したいです
3
+ 階乗を計算したい。
4
- n > rは前提としています。また、オーバーフローもないものとしています。
5
-
6
4
  申し訳ありませんが、バージョンは分かりません。
7
5
  SPIMを使って実行しています。
8
6
 
@@ -10,65 +8,7 @@
10
8
  https://ja.wikipedia.org/wiki/SPIM
11
9
 
12
10
  ### 作成したコード
13
- ```MIPSアセンブリ言語
14
- .text
11
+ fact:
15
- .globl main
16
-
17
- main: addi $sp, $sp, -12
18
- sw $ra, 0($sp) # 戻り先アドレスの退避
19
- li $v0, 5
20
- syscall
21
- move $a0, $v0 # a0 = n
22
- sw $a0, 4($sp) # a0を退避 必要か微妙
23
- li $v0, 5
24
- syscall
25
- move $a1, $v0 # a1 = r
26
- sw $a1, 8($sp) # a1を退避 必要か微妙
27
- lw $a0, 4($sp)   # combiへ渡す引数a0を持ってくる
28
- lw $a1, 8($sp) # combiへ渡す引数a1を持ってくる
29
- jal combi
30
- move $a0, $v0 # 返ってきた結果をa0に渡す
31
- li $v0, 1 # print_int
32
- syscall
33
- lw $a1, 8($sp)
34
- lw $a0, 4($sp)
35
- lw $ra, 0($sp)
36
- addi $sp, $sp, 12 # スタックに確保した領域の開放
37
- jr $ra
38
-
39
-
40
- combi: addi $sp, $sp, -12
41
- sw $ra, 0($sp) # 戻り先アドレスの退避
42
- sw $a0, 4($sp) # a0の退避
43
- sw $a1, 8($sp) # a1の退避
44
- move $s0, $zero
45
- move $s1, $zero
46
- lw $a0, 4($sp) # a0の復元
47
- jal fact # 引数a0(=n)
48
- move $s0, $v0 # s0 = n!
49
- lw $a0, 8($sp) # a1を復元し、それをa0に入れる
50
- jal fact # 引数a1(=r)
51
- move $s1, $v0 # s1 = r!
52
- lw $a0, 4($sp) # a0の復元
53
- lw $a1, 8($sp) # a1の復元
54
- sub $a0, $a0, $a1 # a0 = a0 - a1(= n - r)
55
- jal fact # 引数a0(=a0-a1)
56
- move $s2, $v0 # s2 = (n-r)!
57
- mult $s1, $s2 # s1 * s2 (=r! * (n-r)!)
58
- mflo $s3 # s3 = Lo
59
- div $s0, $s3 # s0/s3 (=n!/(r!*(n-r)!))
60
- mflo $v0 # v0 = Lo
61
- lw $t1, 8($sp)
62
- lw $t0, 4($sp)
63
- lw $ra, 0($sp)
64
- addi $sp, $sp, 12 # スタックに確保した領域の開放
65
- jr $ra
66
-
67
-
68
- fact: addi $sp, $sp, -12
69
- sw $ra, 0($sp) # 戻り先アドレスの退避
70
- sw $s0, 4($sp) # s0の退避
71
- sw $s1, 8($sp) # s1の退避
72
12
  move $s1, $zero # s1を初期化
73
13
  li $s0, 1 # s0 = 1
74
14
  move $s1, $a0 # 引数a0をs1に移動
@@ -77,31 +17,8 @@
77
17
  mult $s1, $a0 # s1 * a0
78
18
  mflo $s1 # Loの中身をs1に持ってくる
79
19
  bgt $a0, $s0, Loop # s0 > s0 ならばLoop
80
-
81
- lw $s1, 8($sp)
82
- lw $s0, 4($sp)
83
- lw $ra, 0($sp) # 戻り先アドレスの復元
84
- addi $sp, $sp, 12 # スタックに確保した領域の開放
85
- move $v0, $s1
86
- jr $ra
87
-
88
20
  ```
89
- ### 発生している問題・エラーメッセージ
90
- 以下のように0しか返ってきません。
91
- ```
92
- (spim) run
93
- 5
94
- 3
95
- 0(spim)
96
- 6
97
- 2
98
- 0(spim)
99
- ```
100
21
 
101
- ### お聞きしたい
22
+ が間違っているのでしょうか
102
23
 
103
- - 上記のコードの問題点はどこか
104
- - 引数の渡し方がいまいちよくわからないので教えて欲しい(上のコードの渡し方は正しいのか)
105
- - lwはswで退避させた値を退避させた場所から、何度も持ってくることができるのか(できると思って上記のコードは書いています)
106
-
107
24
  よろしくお願いいたします。