• ベストアンサー

アセンブリ言語の質問です。8086アセンブラで「筆算的加減算」のプログ

アセンブリ言語の質問です。8086アセンブラで「筆算的加減算」のプログラムを組むことになりました。 2個の整数(3桁)を入力し、入力エラーも処理する様にしなければなりません。また、   123     234         1        100 +456    -123     +999       -200 ーーーー   ----    ----     ----  579      111      1000       -100 のように表示する事が条件になっています。 プログラムを組む上で、何かアドバイスやヒント等、教えていただけないでしょうか・・?

  • BNR33
  • お礼率14% (5/34)

質問者が選んだベストアンサー

  • ベストアンサー
  • nda23
  • ベストアンサー率54% (777/1415)
回答No.5

全部面倒見ないとイケナイかな。 字数の関係があるから、答えを全ては書けません。 よって、今回は考え方のみ記述しますね。 (1)初期処理  ・セグメントレジスタの設定(既にやっている)  ・初期メッセージの表示 (2)中核処理  これは^Cを入力すれば止まるのだから、  無限ループで良いでしょう。以下のことをします。  (a)数値1の入力を促すメッセージを表示する  (b)数値1を入力する  (c)入力値をチェックする   エラー時はメッセージを表示して(a)に戻る  (d)演算子(+か-)を入力する   上記以外はメッセージを表示して(a)に戻る   (e)数値2の入力を促すメッセージを表示する  (f)数値2を入力する  (g)入力値をチェックする   エラー時はメッセージを表示して(d)に戻る  (h)数値1と数値2を(d)に基づいて加減算する  (i)結果を編集し、表示を行う 観念的なコード  CALL 初期処理 MUGEN: ;ここから(2)  CALL 数値1入力  JC MUGEN ;エラー時は戻る  CALL 演算子入力  JC MUGEN ;エラー時は戻る  CALL 数値2入力  JC MUGEN ;エラー時は戻る  CALL 演算  CALL 結果編集  CALL 表示処理  JMP MUGEN ;戻る 疑問点の指摘 (1)復帰改行 0Ah,0Dh とあるが、普通は0Dh,0Ah 文字通り、 復帰(0Dh)、改行(0Ah)の順に書く。後退法の 心配をしたと思うが、DW擬似命令の場合話で、 DB擬似命令では書いた順にメモリに格納される。 (2)セグメントレジスタの設定 mov ax,Data → mov ax,SEG IN_BUF 20年くらい前にやってたことなんで自信ないが、 こう書くような気がする。それと、COM(TINY) 形式の場合はDSの設定は不要です。 おまじないで入れときましょうか。 (3)OUT_DATA_0など バッファド入出力(機能コード:10)を使えば、 入力値の再表示は不要なので、OUT_DATA_0 等は 不要です。ちょっと工夫が要るけどね。 (4)結果表示領域 結果が何ケタになるのか分からないのに、領域が 1バイト分しかない。 ※ラベルと擬似命令、命令とオペランドの間に空白が ありません。

その他の回答 (4)

  • nda23
  • ベストアンサー率54% (777/1415)
回答No.4

#3です。 いきなり間違ってた。 最後のMOVが間違い 誤:MOV DI,DX 正:MOV DX,DI

BNR33
質問者

補足

一応、途中まで組んでみました。 ;----------------------------- ; 筆算的加減算 ;----------------------------- Code segment Code ends Data segment Data ends Stack segment stack Stack ends ;----------------------------- ; Data Segment ;----------------------------- Data segment IN_BUF db 4 db 0 db 3 dup(0) db 0 VALUE_0 dw 0 ;入力した値1 VALUE_1 dw 0 ;入力した値2 RESULT dw 0 ;結果 EXPRESSION db ' ' ;式 TEN dw 10 OUT_BUF db 0Ah,0Dh ;改行 OUT_DATA_0 db ' ' ;入力した値1を出力 db 0Ah,0Dh ;改行 OUT_EXPRESSION db ' ' ;式 OUT_DATA_1 db ' ' ;入力した値2を出力 db 0Ah,0Dh ;改行 db '------',0Ah,0Dh ;筆算の線と改行 OUT_CODE db ' ' ;符号 OUT_RESULT db ' ' ;計算結果 db 0Ah,0Dh,'$' ;改行と終了 MSG_0 db 'アセンブリ 筆算的出力プログラム',0Ah,0Dh,'$' MSG_1 db '1つめの値を入力してください==>','$' MSG_2 db 0Ah,0Dh db '+か-を入力してください','$' 0Ah,0Dh MSG_3 db '2つめの値を入力してください==>','$' MSG_E db 0Ah,0Dh,'エラー発生!もう一度やり直してください。' Data ends ;----------------------------- ; Stack Segment ;----------------------------- Stack segment stack dw 100h dup(?) Stack ends ;----------------------------- ; Code Segment ;----------------------------- Code segment assume cs:Code,ds:Data,ss:Stack ;----------------------------- ; Program MAIN start ;----------------------------- Main proc near mov ax,Data ;set DATA segment mov ds,ax ;-----------------------------メッセージ出力 mov ah,09h mov dx,offset MSG_0 int 21h mov ah,09h mov dx,offset MSG_3 ;2つめの値 int 21h ;-----------------------------値1の入力 mov ah,09h mov dx,offset MSG_1 int 21h こんな感じなんですけど、続きをどうすればよいか、教えてもらえませんか・・?

  • nda23
  • ベストアンサー率54% (777/1415)
回答No.3

DOS上での話と仮定します。 (1)文字列の入力 文字数の上限を指定して、エコーバックやバックスペースも行う 0Ahという機能コードを使います。 X DB 5 ;入力文字数(符号、数字3桁、リターンを含む) N DB ? ;実際に入力されたバイト数が返る領域 D DB 5 DUP (?) ;入力領域   MOV AH,0Ah   MOV DX,OFFSET X   INT 21h (2)入力チェックと数値変換  AXに変換値が入る。Cy=0:正常/Cy=1:エラー CONV:   MOV BX,1 ;BH←0、BL←1   MOV SI,OFFSET N ;実入力バイト数のアドレス   CLD ;デクリメントフラグクリア   LODSB ;AL←[SI++]=実入力バイト数   CBW ;符号拡張(AH←0)   CDW ;符号拡張(DX←0)   XCHG AX,CX ;CX←実入力バイト数   JCXZ C4 ;CX=0(未入力)なら出口へ分岐 C1:   LODSB ;AL←[SI++]   CMP AL,'+'   JE C2 ;"+"であればC2へ分岐   CMP AL,'-'   JNE C3 ;"-"でなければC3へ分岐 C2:   OR BH,BH ;最初かどうか調べる   JNZ C4 ;最初でなければ出口へ分岐 C3:   SUB AL,'0' ;文字コードを減じて数値化する   JB C4 ;0未満なら出口へ分岐   CMP AL,9 ;9と比較   JA C4 ;9より大きければ出口へ分岐   CBW ;符号拡張(AH←0)   XCHG AX,DI ;数値をDIに退避   MOV AX,10 ;10倍するための定数   MUL DX ;既存の値を10倍   ADD AX,DI ;先程の数値を加算   MOV DX,AX ;DXに変換値を記録   OR BH,1 ;文字が検査済みであることを記録   LOOP C1 ;--CX !=0 ならC1へ分岐   DEC BX ;BL←0(ここまで来れば正常)   CMP BH,'-' ;ハイフンがあったか調べる   JNZ C4 ;ハイフンが無ければ出口へ分岐   NEG AX ;マイナスにする C4:   SHR BL,1 ;BLを右シフトしてCyへ結果を反映させる   RET (3)数値表示  AXに数値があるとする B DB 5 DUP (?) ;文字格納領域  DB 0Dh,0Ah,'$' ;復帰、改行、終端記号 DISP:   MOV DI,OFFSET B[5];ポインタを初期化   XOR CX,CX ;CX←0 符号   MOV BL,10 ;定数   OR AX,AX ;マイナスかどうか調べる   JGE D1   INC CX ;マイナスを記録   NEG AX D1:   CBW ;符号拡張   DIV BL ;AXをBLで除算   XCHG AL,AH ;商と剰余を入れ替える   ADD AL,'0' ;文字コード化する   DEC DI ;ポインタを更新する   MOV [DI],AL ;格納する   XCHG AL,AH ;商と剰余を入れ替える   OR AL,AL ;0かどうかを調べる   JNZ D1 ;ゼロでなければ続ける   JCXZ D2;CX=0なら分岐   DEC DI ;ポインタを更新する   MOV [DI],BYTE PTR '-' ;符号を格納する D2:   MOV AH,09h ;機能コード   MOV DI,DX ;データ領域   INT 21h   RET 途中、レジスタの使い方とか、突っ込まれても 大丈夫なように、よく噛み砕いて使ってください。 あと、デバッグしてないから間違ってたらゴメン

  • php504
  • ベストアンサー率42% (926/2160)
回答No.2

プログラムを組む上でのアドバイスではなくて恐縮ですが質問をする上でのアドバイスを 質問するときは環境を具体的に書かれたほうがいいです アセンブラの種類やパソコンのOSなどできるだけ細かいほうがいいですね プログラムの仕様ももっと詳しい方が回答も得られやすいです 実際の入力と出力の例も書いたほうがいいです あと一番いいのは自分が書いたコードをコピーしてアドバイスを求めることですね

  • yama1718
  • ベストアンサー率41% (670/1618)
回答No.1

別に普通に加算命令(ADD,ADC)と減算命令(SUB,SBB)を使えば良いだけじゃないですか? レジスタは16bitなので3桁の整数など余裕で扱えるし、他に二進化十進数やアンパック十進数で計算する方法もあります、その為の命令もありますしね。 それよりも入力や出力で数値を変換する部分が大変ですね。 普通はBIOSやAPIなどで入出力の仕様が定義されていて、それに合わせて変換するサブルーチンを作って呼び出しますね。

関連するQ&A

  • アセンブリ言語

    アセンブリ言語で『筆算的加減算』でプログラムを作成する演習問題が出ました。4月から習い出し全くわからないので参考にさせて頂きたいです。 実行例は⬇️ 1→123 2→456 計算→+  123 +456 --------  579 条件は 入力する2個の整数は正(+)のみとする。 入力する整数の桁数は3桁以内。 足し算は+、引き算はマイナス-を入力する。 負の値は入力しないが、結果の負('-')は表示する。 入力のエラー処理を行う。

  • アセンブリ言語について。

    アセンブリ言語がアセンブラ&実行出来るサイトを知らないでしょうか?また、アセンブリ言語のプログラムが載っているサイトを知らないでしょうか?教えて頂けると幸いです。

  • アセンブリ言語は原始プログラムですか?

    質問(1) アセンブリ言語というのは、 add $S1, $S2 みたいなやつですよね? wikipediaで「ソースコード(ソースプログラム、原始プログラム)」の注釈1,2を読むと、 注1:【機械語の命令に記述するアセンブリ言語(アセンブラ)が存在するが、このアセンブラ用の文字列で記述されたプログラムはソースコードとは呼ばれないのが普通である。】 注2:【アセンブリ言語で書かれたプログラムはソースコードと呼ばれない】 と書かれてあります。 でも、 他の教材では アセンブリ言語で書かれたプログラム(原始プログラム) と書かれています。 どっちが正しいのでしょうか? 質問(2) 目的プログラム(オブジェクトプログラム)とは、 IT用語辞典によると 【オブジェクトプログラムとは、ソースプログラム(人間が認識できるプログラム言語で高水準言語など?)をコンパイラで機械語に翻訳したプログラムのことである】 とありますが、 ソースプログラムをコンパイラで翻訳するとアセンブリ言語になるんではないのですか? そのアセンブリ言語をアセンブラで翻訳して機械語になるのではないのでしょうか? どなたかご教授ください。 お願いします。

  • 最初のアセンブラ

    人間がハンドアセンブル際にアセンブリ言語と機械語の対応表を見比べて翻訳する作業を、コンピュータの黎明期に機械語で最初に作られたアセンブラはどのように行っていたのかということを教えて下さい。 プログラミング言語の歴史を考えてみると、(フォン・ノイマン型)コンピュータの黎明期では全てのプログラムは最初人間が直接真空管やディップスイッチのオン/オフを切り替えることで、機械語でプログラムを入力していたと思います。その後アセンブラが開発されたことで、人間はパンチカードやカセットテープなどを通してアセンブリ言語でプログラミングを行えるようになったと聞きました。 アセンブリ言語は機械語と1対1で結びついたもので、アセンブラはアセンブリ言語を機械語に翻訳するのだと言うことは分かります。しかし、パンチカードやカセットテープで入力したアセンブリ言語も、コンピュータにとっては根本的には0/1(スイッチのオン/オフ)という点では変わりはなく、最初のアセンブラはその0/1をどのようにして正しい機械語の0/1に変換することが出来たのでしょうか? 少し質問の意味が分かりにくいかもしれませんが、例えば MOV B, A //Bレジスタの内容をAレジスタに送る といったアセンブリ言語は、機械語では 01000000 に相当するかもしれません。しかしコンピュータがパンチカードを読み込んだ時点では 01010100 といった信号として入力されるとしたら、機械語で最初にアセンブラを作成した人はどのようにしてそれを適切な機械語(ここでは01000000)に翻訳出来たのでしょうか? 想像では最初に機械語で非常に超簡単なアセンブラの原型とも言えるプログラムを作って、それを元にした簡単なアセンブリ言語(の原型)でより高度なアセンブラを作る、といったことを繰り返していまのアセンブラが開発されていったと思いますが、では最初のアセンブラの原型とはメモリ上ではどのように実現されていたのか、ということが気になったので質問させていただきました。アセンブリ言語で実際にプログラムのイメージはこんな感じでは?ということを書いて下さっても構いません。 よろしくお願い致します。

  • アセンブラ、アセンブリ言語の書籍について

    会社で、ルネサスのSRA74というアセンブラを扱うことになりました。 アセンブリ言語については全くの素人なので本を購入しようとしたのですが、PIC、H8、Z80などはあるのですが、SRA74に該当する書籍がありません。 下記アドレスのガイドブックを見てもいまいちわからないのですが、学習する上で良い書籍や方法はないでしょうか? <http://documentation.renesas.com/jpn/products/tool/rjj10j1252_sra74_g.pdf> どうかよろしくお願いします。

  • アセンブリ言語について

    現在電気工学科の学生です。アセンブリ言語の講義を受けているんですが、試験で単位が取れる自信がありません。。。全くわからないことだらけです。C言語に関してはほんの触りだけ勉強したことがありますが、アセンブラ言語については全くの素人です。演習問題があるんですが、色々本等で探しても見つかりませんでした・・・私の努力不足かもしれませんが、問題の解答と解説を教えて欲しいです。 問題は→メモリアドレス3000H~30FFHの内容(データ)を2000Hから始まるメモリアドレスにコピー(格納)するプログラムをアセンブリ言語で書いてください!それとこの問題には参考のためにアセンブリ言語の命令の例があるんですが LD A、(BC) LD A、(DE) LD A、(HL) って書いてあるんですが、このBCやDE,HLはどんな意味があるんでしょうか?初歩的なことばかりで申し訳ありませんが、ご教授よろしくお願いします。

  • CASL(アセンブラ言語)に関する問題です!

    100,98,94,86,70,38・・・ と、2の倍々で減っていく階差数列の和が初めて負になる項を求めるプログラムをアセンブラ言語で組みたいのですが組み方がわかりません。 ヒントだけでも頂けるとありがたいです!

  • ■ アセンブリ言語の入門書について ■

    アセンブリ言語の入門書を探しております。 アセンブリ言語を通して、コンピューターの動きを勉強したいと考えています。 特にCPUの種類は問いませんが、x86に繋がるような内容を希望しています。 候補としましては、「はじめて読む8086」や「アセンブリ言語スタートブック」が上がっています。 1.図解を主に用いて分かりやすく解説している 2.CPU内の各種回路をどのように流れて処理をするかを図を用いて解説している 以上の条件に合ったような書籍をお心当たりのある方、教えて頂ければ助かります。 よろしくお願いいたします。

  • 64ビットWindows上でアセンブリ言語

    こんにちは。 現在、OSは現在、64ビット版のWindows7を使っています。 このWindows7上で、アセンブリ言語によるプログラミングを行いたいと思っています。 どうして今頃アセンブリ言語なのかといいますと、会社の研修で、C言語による組込みソフトウェア開発を学ぶ際に、アセンブリ言語も学習するらしいので、少し予習してみようと思いました。 そこで、64ビット環境でも動作するアセンブラを探してみたのですが、 なかなか見つからず、困っています。 ネット上の情報を頼りに色々と試したのですが、作成した実行ファイルをいざ実行しようとすると、「64ビット環境では動作しない」といった内容のメッセージが出たりして、 どうしても動作してくれませんでした。 64ビット版のWindows上で、アセンブリ言語によるプログラミングができている方がいらっしゃれば、どうやってできたのかを、是非教えて頂きたいです。 必要であれば、インストールすべきソフトウェアの一覧と、環境設定方法なども、簡単に説明して頂ければ、大変助かります。 あと、動作確認を行う簡単なサンプルプログラムも、提示して頂ければ大変助かります。 (なにせ、アセンブリ言語に関する知識がゼロなものですので。) では、よろしくお願い致します。

  • アセンブリ言語の初歩的な質問です

    xを入れたらx!を返すような階乗のプログラムをアセンブリ言語で作りたいので、頑張っているのですが ADD EAX EBXとすればEAX=EBX+EAXという足し算になりますよね。 そこで掛け算を行うようなものを入力したいのですが EAX*EBXは(掛け算は) MUL EAX EBX とすればいいのでしょうか?

専門家に質問してみよう