
私は、現在情報工学科の学生です。現在学校で8085系プログラムの授業を受講しているのですが、私が作成したプログラムで、axbの部分でどうして[01x00]が動かないのかがわかりません。ちなみに[00x01]は動きました。また、他の数字でaxb(02x03等)を試してみましたが動きました。
もしよければアセンブリ言語での8085系のプログラミングでこの質問に対する回答と解説のご教授お願いします。
問題:データa,bをキーボードから入力すると計算結果が表示素子に表示されるようにしなさい。a,bを入力後、両方を同時にいったん素子に表示して、[STEP]キーで積を表示すること。
・私が考えたプログラミング・
.8085
ASEG
DISPEQU0040H
DHEX1EQU0043H
DHEX2EQU0046H
KEYINEQU004FH
ORG 8000H
CALLINITIALIZATION
L1:CALLKEYIN
JNCL1
CPI14H
JZL1
MVIC,4
CALLDHEX1
CALLDISP
RLC
RLC
RLC
RLC
MOVD,A
L2:CALLKEYIN
JNCL2
ORAD
MVIC,5
CALLDHEX2
CALLDISP
STA9000H
STAaa
LDAdd
STA0FF4DH
;
L3:CALLKEYIN
JNCL3
CPI14H
JZL3
MVIC,2
CALLDHEX1
CALLDISP
RLC
RLC
RLC
RLC
MOVD,A
L4:CALLKEYIN
JNCL4
ORAD
MVIC,3
CALLDHEX2
CALLDISP
STA9001H
STAbb
;
ANS:CALLKEYIN
JNCANS
CPI15H
JNZANS
;
LDAaa
MOVE,A
LDAbb
MOVC,A
;
LOOP:DADD
DCRC
JNZLOOP
SHLD9002H
MVIC,3
MOVA,L
CALLDHEX2
CALLDISP
MVIC,5
MOVA,H
CALLDHEX2
CALLDISP
;
LIGHT_OFF:
CALLKEYIN
JNCLIGHT_OFF
CPI17H
CALLCLEAN
JNZLIGHT_OFF
HLT
;
CLEAN:LDAdd
STA0FF4DH
STA0FF4EH
STA0FF4FH
STA0FF50H
STA0FF51H
STA0FF52H
STA0FF53H
CALL0040H
RET
;
INITIALIZATION:
LDAdd
LXIB,00H
LXID,00H
LXIH,00H
STA9000H
STA9001H
STA9002H
RET
;
aa: DB 00H
bb: DB 00H
dd: DB 00H
;
END
私は自分で考え、もし9001番地などが0ならば、強制的に0を4桁出すプログラムを考えました。しかしどこでそれを入れれば良いのかがわかりません。ヒントだけでもいいので教えてください。
No.4ベストアンサー
- 回答日時:
Tacosanさんが#2で回答されていることを試してみてください。
問題となっているところは乗算をしている58行目から66行目までにあります。ほかは(概ね)問題ありませんのでこの部分に集中してください。
61行目のMOV C,Aまで実行したとき、各レジスタに入っている値の意味を整理しましょう。それぞれのレジスタにはどういう値が入っていてどういう役割を持っていますか。HLレジスタペアはどうですか。DEレジスタペアは?。そしてCレジスタには何が入っていますか?
63行目のループに入った後、66行目で結果を格納するまでこのプログラムはどうやってかけ算を実行していますか?
一ステップずつプロセッサの動きを追ってみましょう。
うまくいっているときの動きの追い方はこんな感じです。
うまくいっている例として、03 02を入力したときです。
61行目まで実行すると各レジスタはこんな値になっているはずです。
HL=0000, DE=0003, C=02
あなたが考えたのと一致していますか?
次に63行目にすすみ、DAD D命令を実行します。レジスタは
HL=0003, DE=0003, C=02 (HLにDEの値が加算された)
あなたの想定通りですか?
64行目に進んでDCR Cを実行します。
HL=0003, DE=0003, C=01 [NZ]
Cレジスタの値が1減ります。フラグはNZです。
65行目に進むとZフラグが立っていないのでJNZ命令を実行してLOOP:ラベルに戻ります。
63行目に戻ってDAD Dを実行します。レジスタは
HL=0006, DE=0003, C=01
64行目、DCR Cを実行
HL=0006, DE=0003, C=00 [Z}
65行目、フラグがZなのでJNZでのジャンプは行われず66行目へすすみます。
66行目、SHLDを実行してHLレジスタに入っている0006が9002H,9003H番地のメモリに書き込まれます。
どうですか?あなたが想定した動きでしょうか。
これと同じことを問題の「うまく動かない」という状況の時にどうなっているか考えてみてください。61行目に達したときレジスタの値はどうなっていますか?そこから63行目、64行目と実行を進めてください。
ところで、#1への返答で「01x00のとき0100と表示されてしまう(0000となって欲しいのに)」ということを書かれていますね。"0100"と表示されるのはなぜか、この値はいったいどこからやってきたのか、というところからデバッグするという考え方もあります。でも、今回はまず上に示したようなステップを追う方法で考えてみてください。
動作を丁寧に追っていけば、「なぜ0100と表示されるのか」もわかると思います。
=========
ここからkfd03077さんへ:(質問者の方済みません。ちょっと貸してください。)
このアセンブリ言語で用いている"DB"命令は「カレントロケーション(メモリ)にオペランドで示す値を格納する」という疑似命令です。"DB 0"で、メモリ上に1バイトの空間を確保し、それをオペランドの値0に初期化します。
DB命令で確保した空間にaa:, bb:などといったラベル(アドレスを示す)をつけているわけですのでこのコードで問題ありません。
つまり、メモリのどこかの1バイトに0(DBのオペランド)が格納され、aaとかbbとかはそのアドレスの値になっています。
おそらくほかのプロセッサ(8086など)のアセンブリ言語にある型付き定数定義と混同されているのだと思います。
この回答への補足
教えてくださってありがとうございます。なぜ[01 x 00]=[0100]になってしまうのか、わかりました。bb(C)ループカウンタの値が-1できないのでできないということはわかったのですが、それをどう直したら良いのかわからないので、プログラムで直し方だけでもいいので教えてください
補足日時:2008/05/16 15:23No.7
- 回答日時:
>教えてくださってありがとうございます。
なぜ[01 x 00]=[0100]になってしまうのか、わかりました。プログラムの動作は理解されたのだと考えてコメントします。
まず、
>bb(C)ループカウンタの値が-1できないのでできないということはわかった
ということですが、正確には「-1(デクリメント)できない」のではなく、「(0から)デクリメントすると桁借りが起こって255になってしまう」ということは理解されていますか?
このプログラムのかけ算の仕組みは、bbの値(61行目でCレジスタに入る)の数だけ63行目のDAD Dを繰り返すこと、にあります。それは理解していますね?
では、bbの値が0のとき、63行目のDAD Dは何回繰り返されますか?そしてそれは本来何回になっているべきだと考えますか?
それで、その本来の回数だけDAD Dを実行するようにするにはどうしたらよいでしょう。
これらの問いにわかる範囲でいいのであなたの考えを書いてください。それでピンとこないようでしたら、具体的な例を示します。
No.5
- 回答日時:
ANo.3 です。
ANo.4 さん、解説ありがとうございます。
> "DB"命令は
そうなんですか。私が触れてた頃のアセンブラは
DB ; Define Byte (8bit の値定義)
DW ; Define Word (16bit の値定義)
だったので、あれ?と思ったのでした。
後には DEFB, DEFW だったりしますが。
ともあれ、私の心配は無用だったわけですね。
どうもお騒がせしてすみませんでした。
No.3
- 回答日時:
レジスタの値がどう変化していくか追うことになりますが、
多くて覚え切れない場合は
Excel を利用するなどして横長に並べ
無駄気味でも全部のレジスタ値の追跡するとモレなく追えます。
尚、以下のサブルーチンの動作が不明確だったので
追うのはやめておきました。
DISP EQU 0040H
DHEX1 EQU 0043H
DHEX2 EQU 0046H
KEYIN EQU 004FH
ところで
LDA bb
STA bb
について、この命令は「値が示すメモリ番地とレジスタAとの間の転送」
です、値 aa, bb, dd はバイト定義なのでアドレスにしては
変な気がしますけどこれは意図通りですか?
すると 0番地付近に書き込んだりしてますが
開発システムがこれを許してるのでしょうか...?
8085 は 0 番地はリセットエントリですから、普通は変です。
(許すシステムもありますが)
No.2
- 回答日時:
#1 にある「その後LOOP:以降に進むとどういう動きになりますか?」というところを, 8085 の気持ちになって実行すればわかると思います.
もっとはっきりいうと, C が 0 のときにこのループは何回実行されますか?
No.1
- 回答日時:
なかなかよく書けていると思います。
本題に入る前に2,3注文を。
まず「動かない」とはどう動かないのかを書くようにしてください。あなたがどうなることを期待しているのか(なのに違う結果になってしまう)がわからないと答えられないことがあります。例えば、このプログラムは01x00を計算しようとするとどうなりますか?暴走するのですか?それとも何か答えを返しますか?
それからアセンブリ言語のコードは長くなりがちですから、コードの位置を示せるように行番号などをつけてもらうか、細かくラベルまたはコメントを入れるようにしてください。例えば9行目のあたりには"; 被乗数の入力"、32行目あたりには"; 乗数の入力"、53行目には"; STEPキーの入力待ち"、58行目には"; aaとbbの値を取り出して乗算(aa*bb)を計算する"などです。
私が昔いた会社では全ての行にコメントを書くこと、という決まりがあったらしいです。それはやり過ぎかもしれませんが初心者のうちは細かくコメントを書くのが考えの整理という意味でも望ましいです。
本題ですが、乗算をしている58行目から66行目までのどこかに問題があることは明らかです。大した長さのコードではないので頭の中(あるいは実機があればそれでもいいですが)で一命令ずつプロセッサがどう動いているかを考えて動作を(期待しているのと違わないか)確認してください。
特に問題は乗数が00のとき、とわかっているので61行目のMOV C,Aを実行した後にCレジスタの内容が00Hになっているケースです。その後LOOP:以降に進むとどういう動きになりますか?
このくらいのヒントでどうでしょうか。まだピンとこないようでしたらもうちょっと細かく解説します。が、ここまでコードを書けるのならこれくらいでわかりそうかと思います。
ところで、乗算の仕方は非常に単純な方法でこれはこれで有用なケースもありますが一般的にはちょっと効率が悪いです。出題者の意向がわからないのでこれでOKなのかもしれませんが、「乗算 アルゴリズム」などとして検索してみるともうちょっと様々な(フツーにマトモなものからどうしてそうなるのかちょっと見ではわかりにくいものまで)計算方法が見つかります。
興味があればそういうのも勉強してみてください。
この回答への補足
結果を書きいてないという指摘をしてくださってありがとうございます。結果ですが、まず[00 x 01]は[0000]と表示されます。しかし
[01 x 00]は[0100]と表示されてしまい、掛け算が行われません。そのほかの計算はすべて正常動作します。bの値が0のとき、動きません。
そこを詳しく教えてください
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- C言語・C++・C# このプログラミングの問題を教えてほしいです。 キーボードからデータ数nとn個のデータを入力し、平均値 3 2022/12/19 22:51
- C言語・C++・C# このプログラミングの問題を教えて欲しいです。 キーボードから整数kを入力し、kが配列aの中に何個存在 2 2022/12/19 22:50
- Ruby VBA 2 2023/01/14 14:14
- その他(自然科学) 科学技術計算の仕事について 2 2023/02/04 18:09
- C言語・C++・C# 至急教えてください。プログラミングの問題です。 最初に正の整数nの入力を受け付け、次に分数の分子と分 1 2022/07/19 17:03
- C言語・C++・C# 至急お願いします。プログラミングの問題です。 最初に正の整数nの入力を受け付け、次に分数の分子と分母 3 2022/07/19 17:09
- C言語・C++・C# 至急教えてください。プログラミングの問題です。 malloc関数を使ってください!お願いします! 最 1 2022/07/21 09:28
- その他(プログラミング・Web制作) Pythonを用いたフラッシュ暗算ソフトの開発に必要なもの 2 2023/01/29 02:22
- その他(プログラミング・Web制作) VBA 1 2023/01/19 16:19
- C言語・C++・C# プログラミングの問題です。写真のプログラムの1から10を下のように入力しましたがプログラムが上手くい 3 2022/07/01 23:31
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
!(否定)演算子について
-
H8マイコン C言語でのプロ...
-
収束計算
-
エクセルで特定の列が0表示の場...
-
教えて下さい
-
Excel・Word リサーチ機能を無...
-
VBAでfunctionを利用しようとし...
-
特定のPCだけ動作しないVBAマク...
-
配列数式の解除
-
Excel マクロ VBA プロシー...
-
Excel_マクロ_現在開いているシ...
-
Excel VBAからAccessマクロを実...
-
お助けください!VBAのファイル...
-
UserForm1.Showでエラーになり...
-
ExcelのVBA。public変数の値が...
-
ExcelVBAでPDFを閉じるソース
-
メッセージボックスのOKボタ...
-
エクセルで別のセルにあるふり...
-
一つのTeratermのマクロで複数...
-
秀丸マクロでマクロのURLを開く...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
繰り返し1行~28行までを順順に...
-
MATLABにおける行の挿入方法
-
!(否定)演算子について
-
H8マイコン C言語でのプロ...
-
C言語で余りがマイナスになる場合
-
Z80のフラグレジスタについて
-
C++
-
ExcelのVBAのテクニック
-
Pythonで行列の要素積(アダマ...
-
Matlabのspdiags関数
-
if文について教えてください
-
8085系プログラミングについて
-
matlab、対角行列の作り方
-
五目並べ
-
OPENCVを使ったエピポーラ幾何...
-
mathematicaの質問です
-
cのプログラミングで虚数を含...
-
パイソンのプログラミングにつ...
-
演算装置とフラグレジスタの関係
-
【MATLAB】配列内の数値のキャ...
おすすめ情報