スタックマシン sml0 のアセンブリ言語がわからない。
スタックマシン sml0 のアセンブリ言語がわからない。
(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
その合計を計算して表示するプログラム
(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
Re: スタックマシン sml0 のアセンブリ言語がわからない。
(1)は、提示されたプログラムで即値をスタックに積んでいる所を整数値を読み込む命令に置き換えればできそうですね。
(2)、(3)は、比較命令や分岐命令が無いと難しいと思います。
(「sml0」でググっても、すぐには説明は出なそうでした)
(2)、(3)は、比較命令や分岐命令が無いと難しいと思います。
(「sml0」でググっても、すぐには説明は出なそうでした)
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)
Re: スタックマシン sml0 のアセンブリ言語がわからない。
整数比較 >, >=, <, <=, ==, !=,比較結果は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)の提示されたプログラムで即値をスタックに積んでいる所を整数値を読み込む命令に置き換えればの所で言葉だけじゃわからないのでコードでお願いします。
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 のアセンブリ言語がわからない。
付け加え【注意点】2項演算(加減乗除や比較演算)は、Mnemonic(命令名)はすべて opr2 で、そのオペランドで具体的な演算(例えば、「加算 add(+)」や「より大きい gtr(>)」など)を表現する点に注意。例えば addというMnemonic(命令名)はなく、加算をしたいなら命令語は
opr2, add
と書かねばならない。また、比較(>)をするにも gtrという Mnemonic(命令名)はなく、、
opr2, gtr
と書く必要があるって書いてました。(問題集に)
opr2, add
と書かねばならない。また、比較(>)をするにも gtrという Mnemonic(命令名)はなく、、
opr2, gtr
と書く必要があるって書いてました。(問題集に)
Re: スタックマシン sml0 のアセンブリ言語がわからない。
予想ですが、こんな感じですかね。ビルド さんが書きました:また、(1)の提示されたプログラムで即値をスタックに積んでいる所を整数値を読み込む命令に置き換えればの所で言葉だけじゃわからないのでコードでお願いします。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)
Re: スタックマシン sml0 のアセンブリ言語がわからない。
一番の問題は理解できて、うまく実行できました。
実行結果画面
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なのです。どうすれば小さくない方を表示するのですか、できれば、コード付きでお願いします。
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 のアセンブリ言語がわからない。
次のように書いていますよね。ビルド さんが書きました: 画面をみれば、わかるのですが、なぜか数値が1なのです。
スタック内に 3 と 2 がプッシュされていてビルド さんが書きました:整数比較 >, >=, <, <=, ==, !=,比較結果は1(真)または0(偽)
それらを 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 のアセンブリ言語がわからない。
なぜ、解決なんですか?ビルド さんが書きました:ありがとうございます。
うその命令で書いたコードなのに。
sml0 の本当の命令で書き直してください。
(3) もまだ残ってますよ。
Re: スタックマシン sml0 のアセンブリ言語がわからない。
間違えておしてしまいました。
書きかえました。そして実行しました。
ちなみに命令表です。
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).実行を終了する
書きかえました。そして実行しました。
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 のアセンブリ言語がわからない。
2 と 3 のうち、小さい方の 2 を表示していますよ。ビルド さんが書きました: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.
小さくない方を表示したければ、
7: opr2 gteq にしないといけないのでは?
Re: スタックマシン sml0 のアセンブリ言語がわからない。
あるいは、コードとデータは別のアドレス空間ですか?かずま さんが書きました: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 ; 停止
Re: スタックマシン sml0 のアセンブリ言語がわからない。
nopを入れたほうがよいです。
問2の実行結果
問2はうまく表示されました。
問3の実行結果
結果通り一個しか表示されません。
こういう風に表示されたいです。やはりprintを追加だけでいいのですか。
問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.
問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.
Re: スタックマシン sml0 のアセンブリ言語がわからない。
1ステップずつ、状態がどう変わるか、自分のビルド さんが書きました: 問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.
頭で考えて、紙に書いたりしていますか?
17: opr2 nteq
21: opr2 add
ではありませんか?