なぜこのコードはもっと単純な方法で書かれていないのですか?


8

アセンブリ言語に取り組んでいるときに質問に遭遇しました。ここに質問があります:

ビットP2.2が屋外照明の制御に使用され、ビットP2.5が建物内部の照明の制御に使用されていると仮定します。外光をオンにし、内光をオフにする方法を示します。

与えられた解決策:

SETB C            ; CY = 1
ORL C, P2.2       ; CY = P2.2 ORed w/ CY
MOV P2.2, C       ; turn it on if not on
CLR C             ; CY = 0
ANL C, P2.5       ; CY = P2.5 ANDed w/P2.5
MOV P2.5,C        ; turn it off if not off

私はそれがコーディングするのと同じ仕事をするように感じました:

SETB P2.2
CLR P2.5

それのどこが悪いんだい?


2
多分ちょうど教訓-キャリービットをアキュムレータとして使用する方法を示しています。この特定のケースで私が見ることができる利点はありません。これは、8051アセンブリコードのように見えます。
Spehro Pefhany 2017

@SpehroPefhanyしかし、DA、RR、RLなどのいくつかの命令をサポートする唯一のレジスタであるため、私の知る限りでは、Accレジスタが使用される場合があります。ここではそうではないと思います。私が間違っている?
–İlkerDemirel 2017

キャリーは1ビット幅です。ラダーロジックの評価など、場合によってはアキュムレータとして使用することもできます。
Spehro Pefhany 2017

回答:


11

あなたが示しているコードはばかげているように見えるので、あなたは正しいです。おそらく、これが実行されているどのマシンでも、I / Oポートのビットを設定するための即時操作を実行できません。そのため、SETB P2.2のようなものが不可能です。

それでもCYビットを1に設定してから、それにORを実行しても、ばかげたことはありません。CYビットを0に設定してから、それにANDを適用する場合も同様です。コードがCYビットをI / Oピンビットに直接コピーできることは明らかです。せいぜいこれは4つの命令でなければなりません。確かに6つではありません。


したがって、ビットがアドレス指定可能であれば、どのビットでもビット命令を使用することが許可されていると言えるでしょう。
–İlkerDemirel 2017

1
@İlk:必ずしもそうではありません。ビット命令が特定のレジスタ、特定の「ニア」メモリなどでのみ機能するなどの制限がある場合があります。プロセッサーを知らなければ、SETB P2.2が可能であったかどうかは確かではありません。ただし、SETB Cに続いてMOV P2.2、Cを使用することは明らかに可能です。
Olin Lathrop、2017

1
@OlinLathrop:プロセッサはほぼ間違いなく8051バリアントであり、それらの命令セットにより、と同じ場所をSETB bitCLR bit命令に使用できMOV bit,Cます。さらに、個別の命令を使用してI / Oポートを読み取り、値を更新し、それを書き戻すと、読み取り-変更-書き込み命令を使用した場合とは異なるセマンティクスが生成されますが、ビットごとの命令はすべて、Iで同じ読み取り-変更-書き込みセマンティクスを使用します/ Oポート。
スーパーキャット2017

9

このコードは、8051命令セットを使用するプロセッサ向けです。そのプロセッサーでは、実行するコードのバリエーションは、より速く実行されることを除いて、元のコードと同じ効果があります。キャリーが設定されているときに「ORL C、P2.2」を実行しても、いくつかのサイクルを浪費する以外は、目に見える効果はありません(2つのCPUサイクルで8051を合計すると24クロックサイクルです。 。同様に、キャリーがクリアされているときに「ANL C、P2.5」を実行すると、一部のI / O位置を読み取るリクエストが目に見える影響を与えるような種類のプロセッサがあるかもしれませんが、ビットアドレス指定可能なI / O位置に対して、8051スタイルのプロセッサがそのような動作をしたことはないと思います。 P2のビットでは少なくなります。

おそらく、コードの目的はORL C,bitとのANL C,bit説明を示すことでしたが、これはそれらを説明する奇妙な例のようです。


6

指定されたアセンブリコードは、コンパイラによって生成された可能性があります。これは、次のCステートメントの最適化されていないバージョンです。ここでP2_2、およびP2_5はビットアドレス指定可能なオブジェクトです。

P2_2 |= 1;
P2_5 &= 0;

これはP2_2 = 1;およびと同等に見えるかもしれP2_5 = 0;ませんが、ビットアドレス指定可能なレジスタが揮発性オブジェクトである場合はそうではありません。揮発性オブジェクトに対する読み取り-変更-書き込み操作では、読み取りと書き込みをこの順序で実行する必要があります。これにより、レジスタの読み取りまたは書き込みによる副作用が実際に発生します。

私は副作用のある8051ビットアドレス指定可能なレジスターがないことを知っていますが、コンパイラーが存在しないか、存在しないとは想定できません。


1
コンパイラによって生成される可能性があることについての良い点。ただし、質問がP2_2 = 1だけでなく、なぜP2_2 | = 1と書かれるのかという質問に移ります
Olin Lathrop

3

これらの本当の違いは微妙かもしれません。

簡単な答えでは、ロジックはポートを読み取り、ビット値を設定またはクリアしてから、ポートに書き戻します。ポート全体をここで書き直すことができることに注意してください。

一方、解決策は、かなり異なる方法で動作する可能性のあるMOVビット命令を使用します。

ここで使用されている特定の部分の詳細を説明しないと、違いがあるかどうか、またはそれが重要かどうかを判断することは困難です。

それとも、インストラクターがあなたに考えさせることを決めただけかもしれません...結局のところ、彼の本当の仕事です。


0

唯一の答えは、プロセッサが1ビット命令を直接サポートしていないということです。ただし、キャリービットが使用されている場合、操作されているのは1ビットだけであることがわかります。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.