平成23年秋期午後問12

午前試験免除制度対応!基本情報技術者試験のeラーニング【独習ゼミ】
ゆきぽよさん
(No.1)
https://www.fe-siken.com/kakomon/23_aki/pm12.html
質問です

設問1
bに関する解答群で正答が
JOV  ADJ2
となる理由がよく理解できません。
JMI  ADJ2ではなぜ間違いとなるのでしょうか。

プログラム1は被除数から除数を減算しつつ商をカウントしているので
負になったら終了だろうと考えたのですが。

よろしくお願いします。
2020.09.06 13:40
助け人さん
(No.2)
空欄bの直前のSUBLは、論理減算です。論理演算で扱える16ビットの値の範囲は、0~65535(負の値は扱えない)です。

論理加算のADDLの結果、65535を上回ったときにオーバフローするのは分かりやすいのですが、SUBLの結果、0を下回ったときもオーバフローします。JMIで判定できるのは、算術減算のADDAの結果、0を下回ったときです。

ちょっとした要注意事項ですね。
2020.09.06 17:42
ゆきぽよさん
(No.3)
助け人さま

ありがとうございます
論理減算と算術減算の違いをいいかげんに理解していたようです。
よく分りました。

解説頂いたことは納得できたのですが、新たな疑問が生まれてしまいました。
連続で申し訳ないのですが、宜しければ助言いただけると幸いです。 

このプログラムですと、下位語がオーバフローしたら上位語を1を減算して、
上位語がオーバフローするまでは下位語の論理減算をし続けています。
その下位語の減算は16行目の

SUBL GR7,1,GR3

で行います。
分からないのは下位語がオーバーフローして以降のGR7の値です。

そもそもGR7はループ先でGR5のレジスタに渡されて剰余として扱われるので、
剰余として正の値になると分かってはいるのですが、負の値を扱わないとすると、
論理減算によってGR7には何が入るのでしょうか。

分かりにくかったら申し訳ないありません。伝わりますでしょうか。
2020.09.06 21:25
助け人さん
(No.4)
例えば、
SUBL GR6,0,GR3
を実行前のG6とG7が以下の通りとします。
0000000000000011  0000000000000001
アドレスG3とG3+1にある値がが以下の通りとします。
0000000000000001  0000000000000010

SUBL GR7,1,GR3
を実行後のGR7、つまり、0000000000000001から0000000000000010を論理減算したらどうなるかですね。これだけでは答える自信がありませんが、上記の2語同士を手計算で減算したら、
0000000000000001  1111111111111111
になりますから、GR7は
1111111111111111
になるはずです。まるで、1から2を減算したら-1になるように。

結果論ですみませんが、オーバフローはするけれども、減算した結果は、しっかりと2の補数で表した値になるわけです。

ついでに言えることは、1111111111111111に0000000000000010を論理加算したら、オーバフローはするけれども、0000000000000001になります。
2020.09.06 23:13
ゆきぽよさん
(No.5)
重ね重ねありがとうございます。

>オーバフローはするけれども、減算した結果は、しっかりと2の補数で表した値になるわけです。

補数表現で負の値となると私も思うのですが、
本問の場合はこのGR7のコピーが処理終了時に剰余になるのです。
剰余が負になるのはおかしい気がするのです。どうでしょうか。

また一番初めに質問させて頂きました疑問に関して、
類似の処理を探したのですが、
平成29年度春期のアセンブラ[プログラム2]があります。
これなども本問同様に符号なし整数を扱う処理ですが、

SUBL GR6,=16
JMI  LOWORD

とする箇所がありました。
論理減算をして結果の負/非負で分岐させていますから、
SFはフラグとして使用できると思うのです。

するとまた当初の疑問で堂々巡りをしてしまうのですね。
本問ではOFを使用してJOVで分岐をさせると正しく、
SFを使用してJMIで分岐すると誤りとなる…なかなか分からないです。

何かを見落としているのは確実なのですが…。
根本的な理解がまだまだなので、これからもご助力を賜りつつ
もう少し考えて見たいと思いますが、もう出題されないことを願うばかりですね笑
2020.09.07 19:17
助け人さん
(No.6)
うまく答えられなくてあまり期待に沿えないかもしれませんが、精一杯書いてみます。長くなるので、2回に分けて投稿します。

①「補数表現で負の値となると私も思うのですが、本問の場合はこのGR7のコピーが処理終了時に剰余になるのです。剰余が負になるのはおかしい気がするのです。どうでしょうか。」の件

0000000000000011  0000000000000001  を
0000000000000001  0000000000000010  で割った剰余を求めるために、
0000000000000011  0000000000000001  から
0000000000000001  0000000000000010  を引いて
0000000000000001  1111111111111111  です。

このとき、下位16ビットだけを見ると、
0000000000000001  から
0000000000000010  を引くのですが、引ききれないので、上位16ビットから1を借りて、
1  0000000000000001  から
0  0000000000000010  を引いて
0  1111111111111111  です。

1111111111111111  だけを見ると、一見、2の補数で-1ですが、実際は、2^^16-1という正の数です。

引き算の続きをやると、
0000000000000001  1111111111111111  から
0000000000000001  0000000000000010  を引いて
0000000000000000  1111111111111101  となり、これが剰余です。
2020.09.07 21:09
助け人さん
(No.7)
②「平成29年度春期のSUBL GR6,=16  JMI LOWORD」の件

自信がありませんので、独り言として見てください。

【結論】選択肢にないJOVでも正しい。一方、平成23年秋期は、JOVは正しいが、JMIは間違い(両方とも選択肢にあり、JOVを答えさせる)。

平成29年度春期をしっかりと見ていませんが、GR6は、どんなに大きな数値になっても最初のビットが1にはならないのではありませんか(ここ、大事)?そのGR6から16を引き続けて負の数に転じると、OF、SFともに1になります。

一方、平成23年秋期では、GR7の最初のビットが1のときがあり、例えば、
1010101010101010  から
0000000000000001  を引いて
1010101010101001  となり、OFは0ですが、最初のビットが1だからSFが1になります。つまり、GR7から引ききれてもSFが1になることがあり、そのときにJMI ADJ2ではマズイのです。

このように考えたのは、次の内容をネットで見つけたからです。
--------------------------------------
論理加算で、
0111111111111111  に
0000000000000001  を足すと
1000000000000000  になり、これは正の数(2^^15)であるが、最初のビットが1だからSFが1になる。
--------------------------------------

(私には)とても難しいです。ご健闘を祈ります。
2020.09.07 21:38
ゆきぽよさん
(No.8)
この投稿は投稿者により削除されました。(2020.09.08 00:52)
2020.09.08 00:52
ゆきぽよさん
(No.9)
まずはお礼を述べさせていただきます。
未熟者の質問ですのでお答えいただくだけでも大変かと存じます。

ですがお蔭さまで解決したかもしれません。

下位語がオーバフローし、それだけ見れば2の補数ですが、上位語と合わせれば正の値ですね。

どうやら勘違いの原因が見えてきました。
上位語と下位語のレジスタに、それぞれ独立した値が格納されているように錯覚したようです。上位語と下位語で合わせて一つの値ですね。

ご指摘を受けてJMIを使ってはいけない理由も見えてきました。

もしJMIを使ってしまうと、以降のループで最上位が1の間はSF=1ですから、
毎回上位語から1を差し引くことになってしまうということですね。
桁を借りるのはオーバーフローした時のみでないとおかしいですね。

少しづつ分かってきました。
長々お付き合いいただきまして感謝にたえません。
私にとってはさらに難しいのですが…笑
もう少しですので努力したいと思います。ありがとうございました。
2020.09.08 00:54

返信投稿用フォーム

スパム防止のために初投稿日から10日以上経過したスレッドへの書き込みは禁止しています。

その他のスレッド


Pagetop