スタックマシン sml0 のアセンブリ言語がわからない。

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
ビルド

スタックマシン sml0 のアセンブリ言語がわからない。

#1

投稿記事 by ビルド » 7年前

(1)キーボードから2つの整数値を読み、
その合計を計算して表示するプログラム

(2)キーボードから2つの整数値を読み、
その内の小さくない方を表示するプログラム

(3)キーボードから2つの整数値を読み、
大きくない方から小さくない方までの整数をつぎつぎと
表示する
3つのプログラムの問題ですが、どのようなプログラムを打てばよいのですか?
コード付きでお願いします。

◆ちなみに私はsample.txtを作った。
そこらへんは理解できた。説明をコメントに記載したものである。
下のプログラムや実行結果を参考にしてください。

0, nop, -1 ; なにもしない
1, read, -1 ; 整数値をひとつ読み込む(スタックに積む) それを nとしておく
2, ldi, 2 ; 数値 2をスタックに積む(2は命令語中にあり、即値と呼ばれる)
3, opr2, add ; 2項演算のadd(加算 n+2)をスタック上で実行する
4, print, -1 ; スタックトップを表示して、popする
5, halt, -1 ; 停止する
実行結果sample.txt

コード:

C:\...(省略)...\windowsExe>sml0x86.exe SampleProgForSml0\sample.txt
   0:     nop      -1
   1:    read      -1
   2:     ldi       2
   3:    opr2     add
   4:   print      -1
   5:    halt      -1
Executing program...
? 10
12
(debug): stack_ptr = 0; If non 0, something is WRONG!
Execution terminated.

C:\...(省略)...\windowsExe>

アバター
みけCAT
記事: 6734
登録日時: 14年前
住所: 千葉県
連絡を取る:

Re: スタックマシン sml0 のアセンブリ言語がわからない。

#2

投稿記事 by みけCAT » 7年前

(1)は、提示されたプログラムで即値をスタックに積んでいる所を整数値を読み込む命令に置き換えればできそうですね。
(2)、(3)は、比較命令や分岐命令が無いと難しいと思います。
(「sml0」でググっても、すぐには説明は出なそうでした)
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

ビルド

Re: スタックマシン sml0 のアセンブリ言語がわからない。

#3

投稿記事 by ビルド » 7年前

整数比較 >, >=, <, <=, ==, !=,比較結果は1(真)または0(偽)
less = 20,/* <, less than */
lseq, /* <=, less than or equal to */
gteq, /* >=, greater than or equal to */
gtr, /* >, greater than */
equ, /* ==, equal to */
nteq, /* !=, not equal to */

これが比較命令と分岐命令である。
また、(1)の提示されたプログラムで即値をスタックに積んでいる所を整数値を読み込む命令に置き換えればの所で言葉だけじゃわからないのでコードでお願いします。

ビルド

Re: スタックマシン sml0 のアセンブリ言語がわからない。

#4

投稿記事 by ビルド » 7年前

付け加え【注意点】2項演算(加減乗除や比較演算)は、Mnemonic(命令名)はすべて opr2 で、そのオペランドで具体的な演算(例えば、「加算 add(+)」や「より大きい gtr(>)」など)を表現する点に注意。例えば addというMnemonic(命令名)はなく、加算をしたいなら命令語は
opr2, add
と書かねばならない。また、比較(>)をするにも gtrという Mnemonic(命令名)はなく、、
opr2, gtr
と書く必要があるって書いてました。(問題集に)

アバター
みけCAT
記事: 6734
登録日時: 14年前
住所: 千葉県
連絡を取る:

Re: スタックマシン sml0 のアセンブリ言語がわからない。

#5

投稿記事 by みけCAT » 7年前

ビルド さんが書きました:また、(1)の提示されたプログラムで即値をスタックに積んでいる所を整数値を読み込む命令に置き換えればの所で言葉だけじゃわからないのでコードでお願いします。
予想ですが、こんな感じですかね。

コード:

0, nop, -1 ; なにもしない
1, read, -1 ; 整数値をひとつ読み込む(スタックに積む) それを nとしておく
2, read, -1 ; 整数値をひとつ読み込む(スタックに積む) それを mとしておく
3, opr2, add ; 2項演算のadd(加算 n+m)をスタック上で実行する
4, print, -1 ; スタックトップを表示して、popする
5, halt, -1 ; 停止する
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

ビルド

Re: スタックマシン sml0 のアセンブリ言語がわからない。

#6

投稿記事 by ビルド » 7年前

一番の問題は理解できて、うまく実行できました。

コード:

0, nop, -1
1, read, -1
2, read, -1
3, opr2, gtr
4, print, -1
5, halt, -1
実行結果画面
C:\workC>sml0x86.exe sample(2).txt
0: nop -1
1: read -1
2: read -1
3: opr2 gtr
4: print -1
5: halt -1
Executing program...
? 3
? 2
1
(debug): stack_ptr = 0; If non 0, something is WRONG!
Execution terminated.

C:\workC>

そこで、問2の問題で、小さくない方を表示するプログラムにしたいのですが、画面をみれば、わかるのですが、なぜか数値が1なのです。どうすれば小さくない方を表示するのですか、できれば、コード付きでお願いします。

かずま

Re: スタックマシン sml0 のアセンブリ言語がわからない。

#7

投稿記事 by かずま » 7年前

ビルド さんが書きました: 画面をみれば、わかるのですが、なぜか数値が1なのです。
次のように書いていますよね。
ビルド さんが書きました:整数比較 >, >=, <, <=, ==, !=,比較結果は1(真)または0(偽)
スタック内に 3 と 2 がプッシュされていて
それらを pop し比較すると、3 は 2 より
greater だから、結果の 1 を push
ビルド さんが書きました: どうすれば小さくない方を表示するのですか、できれば、コード付きでお願いします。
load/store命令や、分岐命令が必要です。
sml0 の仕様がわからないので、無条件ジャンプ命令 goto と
条件ジャンプ命令 ifzero を勝手に作ってみました。

コード:

 1: read   -1  ; 整数値を読み込みスタックに積む(push)
 2: store  15  ; スタックトップを指定アドレスに格納し、pop
 3: read   -1  ; 整数値を読み込みスタックに積む(push)
 4: store  16  ; スタックトップを指定アドレスに格納し、pop
 5: load   15  ; 指定アドレスの整数値を push
 6: load   16  ; 指定アドレスの整数値を push
 7: opr2 less  ; 2項演算 less をスタック上で実行。結果は 0 or 1
 8: ifzero 12  ; スタックトップが 0 なら指定アドレスにジャンプし、pop
 9: load   15  ; 指定アドレスの整数値を push
10: print  -1  ; スタックトップを表示して、pop
11: goto   14  ; 指定アドレスに無条件ジャンプ
12: load   16  ; 指定アドレスの整数値を push
13: print  -1  ; スタックトップを表示して、pop
14: halt   -1  ; 停止する
15: word    0  ; 整数値格納領域
16: word    0  ; 整数値格納領域


かずま

Re: スタックマシン sml0 のアセンブリ言語がわからない。

#9

投稿記事 by かずま » 7年前

ビルド さんが書きました:ありがとうございます。
なぜ、解決なんですか?
うその命令で書いたコードなのに。
sml0 の本当の命令で書き直してください。
(3) もまだ残ってますよ。

ビルド

Re: スタックマシン sml0 のアセンブリ言語がわからない。

#10

投稿記事 by ビルド » 7年前

間違えておしてしまいました。
書きかえました。そして実行しました。

コード:

C:\workC>sml0x86.exe sample(2).txt
   0:     nop      -1
   1:    read      -1
   2:   store      15
   3:    read      -1
   4:   store      16
   5:    load      15
   6:    load      16
   7:    opr2    less
   8:   cjump      12
   9:    load      15
  10:   print      -1
  11:    jump      14
  12:    load      16
  13:   print      -1
  14:    halt      -1
Executing program...
? 2
? 3
2
(debug): stack_ptr = 0; If non 0, something is WRONG!
Execution terminated.
 ちなみに命令表です。
0 nop no operation; なにもせずに pcを1増す(次の命令に進む)
1 ldi operandの即値(immediate value)をstackに積む(load immediate)
2 opr1 operandの即値が示す単項演算(unary operation)をstackに対して実施(operandが1個)
3 opr2 operandの即値が示す2項演算(binary operation)をstackに対して実施(operandが2個)
4 print operandなし(形式的に -1).stackトップの値を表示し,popする
5 read operandなし(形式的に -1).キーボード入力(数値)をstackにpushする
6 jump operandの即値が示す番地(絶対番地)にjump
7 cjump stackトップの値が0(偽)の時jumpし,popする.
そうでない場合単にpopする ※1(真)でjumpではないので注意
8 store stackトップの値をoperand(即値)が示すmem[]の番地に格納し,popする
9 load operand(即値)が示す番地の値をstackに pushする
10 halt operandなし(形式的に -1).実行を終了する

ビルド

Re: スタックマシン sml0 のアセンブリ言語がわからない。

#11

投稿記事 by ビルド » 7年前

問3の問題です。

コード:

0, nop, -1
1, read, -1
2, store, 15
3, read, -1
4, store, 16
5, load, 15
6, load, 16
7, opr2, less
8, cjump,12
9, load, 15
10, print, -1
11, jump, 14
12, load, 16
13, print, -1
14, print, -1
15, halt, -1
間違っていたら訂正してください。

かずま

Re: スタックマシン sml0 のアセンブリ言語がわからない。

#12

投稿記事 by かずま » 7年前

ビルド さんが書きました:

コード:

C:\workC>sml0x86.exe sample(2).txt
   0:     nop      -1
   1:    read      -1
   2:   store      15
   3:    read      -1
   4:   store      16
   5:    load      15
   6:    load      16
   7:    opr2    less
   8:   cjump      12
   9:    load      15
  10:   print      -1
  11:    jump      14
  12:    load      16
  13:   print      -1
  14:    halt      -1
Executing program...
? 2
? 3
2
(debug): stack_ptr = 0; If non 0, something is WRONG!
Execution terminated.
2 と 3 のうち、小さい方の 2 を表示していますよ。

小さくない方を表示したければ、
7: opr2 gteq にしないといけないのでは?

かずま

Re: スタックマシン sml0 のアセンブリ言語がわからない。

#13

投稿記事 by かずま » 7年前

ビルド さんが書きました:問3の問題です。
間違っていたら訂正してください。
間違っています。
実行してみないのですか?

store 15 を実行すると、
halt命令を破壊してしまいます。

入力が 2 と 5 なら、次のようにならないと
いけないのに、そういうコードではありませんね。

コード:

Excecuting program..
? 2
? 5
2
3
4
5
(debug): stack_ptr = 0; If non 0, something is WRONG!
Execution terminated.

かずま

Re: スタックマシン sml0 のアセンブリ言語がわからない。

#14

投稿記事 by かずま » 7年前

かずま さんが書きました:store 15 を実行すると、
halt命令を破壊してしまいます。
あるいは、コードとデータは別のアドレス空間ですか?
それなら、

コード:

 0: nop   -1
 1: read  -1 ; 整数値を読み込んで push
 2: store  0 ; pop した値を mem[0] に格納
 3: read  -1 ; 整数値を読み込んで push
 4: store  1 ; pop した値を mem[1] に格納
 5: load   0 ; mem[0] の値を push
 6: load   1 ; mem[1] の値を push
 7: opr2 gtr ; b と a を pop して、a > b の結果を push
 8: cjump 13 ; pop した値 が 0 なら 13 へ jump
 9: load   0 ; mem[0] の値を push
10: load   1 ; mem[1] の値を push
11: store  0 ; pop した値を mem[0] に格納
12: store  1 ; pop した値を mem[1] に格納
13: load   0 ; mem[0] の値を push
14: print -1 ; pop した値を print
15: load   0 ; mem[0] の値を push
16: load   1 ; mem[1] の値を push
17: opr2 equ ; b と a を pop して、a == b の結果を push
18: cjump 24 ; pop した値 が 0 なら 24 へ jump
19: load   0 ; mem[0] の値を push
20: ldi    1 ; 1 を push
21: add   -1 ; b と a を pop して、a + b の結果を push
22: store  0 ; pop した値を mem[0] に格納
23: jump  13 ; 13 へ jump
24: halt  -1 ; 停止
コードのアドレス0 には nop を入れないといけないんですか?

ビルド

Re: スタックマシン sml0 のアセンブリ言語がわからない。

#15

投稿記事 by ビルド » 7年前

nopを入れたほうがよいです。
問2の実行結果

コード:

C:\workC>sml0Rx86.exe sample(2).txt
   0:     nop      -1
   1:    read      -1
   2:   store      15
   3:    read      -1
   4:   store      16
   5:    load      15
   6:    load      16
   7:    opr2     gtr
   8:   cjump      12
   9:    load      15
  10:   print      -1
  11:    jump      14
  12:    load      16
  13:   print      -1
  14:    halt      -1
Executing program...
? 6
? 5
6
(debug): stack_ptr = 0; If non 0, something is WRONG!
Execution terminated.
問2はうまく表示されました。
問3の実行結果

コード:

C:\workC>sml0Rx86.exe sample(3).txt
   0:     nop      -1
   1:    read      -1
   2:   store       0
   3:    read      -1
   4:   store       1
   5:    load       0
   6:    load       1
   7:    opr2     gtr
   8:   cjump      13
   9:    load       0
  10:    load       1
  11:   store       0
  12:   store       1
  13:    load       0
  14:   print      -1
  15:    load       0
  16:    load       1
  17:    opr2     equ
  18:   cjump      24
  19:    load       0
  20:     ldi       1
  21:    opr2     gtr
  22:   store       0
  23:    jump      13
  24:    halt      -1
Executing program...
? 4
? 5
4
(debug): stack_ptr = 0; If non 0, something is WRONG!
Execution terminated.
結果通り一個しか表示されません。

コード:

Excecuting program..
? 2
? 5
2
3
4
5
(debug): stack_ptr = 0; If non 0, something is WRONG!
Execution terminated.
こういう風に表示されたいです。やはりprintを追加だけでいいのですか。

かずま

Re: スタックマシン sml0 のアセンブリ言語がわからない。

#16

投稿記事 by かずま » 7年前

ビルド さんが書きました: 問2はうまく表示されました。
問3の実行結果

コード:

C:\workC>sml0Rx86.exe sample(3).txt
   0:     nop      -1
   1:    read      -1
   2:   store       0
   3:    read      -1
   4:   store       1
   5:    load       0
   6:    load       1
   7:    opr2     gtr
   8:   cjump      13
   9:    load       0
  10:    load       1
  11:   store       0
  12:   store       1
  13:    load       0
  14:   print      -1
  15:    load       0
  16:    load       1
  17:    opr2     equ
  18:   cjump      24
  19:    load       0
  20:     ldi       1
  21:    opr2     gtr
  22:   store       0
  23:    jump      13
  24:    halt      -1
Executing program...
? 4
? 5
4
(debug): stack_ptr = 0; If non 0, something is WRONG!
Execution terminated.
結果通り一個しか表示されません。
1ステップずつ、状態がどう変わるか、自分の
頭で考えて、紙に書いたりしていますか?

 17: opr2 nteq
 21: opr2 add
ではありませんか?

ビルド

Re: スタックマシン sml0 のアセンブリ言語がわからない。

#17

投稿記事 by ビルド » 7年前

おかげさまでうまく実行できました。ありがとうございました。

返信

“C言語何でも質問掲示板” へ戻る