15

ビットアドレス指定可能なマイクロコントローラーについていくつか調査しました。私のパスで出くわした唯一のものは、今日でも非常に一般的に使用されているIntel MCS-51(wikiページ)です...たとえば、SFR地域のwiki 8051で、Cで少し対処できるかどうか疑問に思っていましたメモリ アーキテクチャ

SFR でアドレス指定するビットは、直接ビット アドレス指定されますか、それともバイト アドレス指定されるビットフィールドでのビット単位の操作ですか、それとも完全に別のものですか?

具体的には、ここから: Check if a single bit is set , ビットが MOV で直接操作されているように見える.背景には、バイトのみを使用するコンパイラーのものがありますか?

フォローアップの質問として、ビットアドレス指定可能な最新のプロセッサはありますか?

4

6 に答える 6

9

プレーンな C (拡張子が何であれ) では、変数をビット フィールドとして宣言できます。大量の入力を節約でき、エラーが発生しにくくなります。

これがプログラムの例です。同じサイズの通常型との共用体でビット フィールドを宣言します。

#include <stdio.h>

int main(int argc, char *argv[])
{
    typedef struct 
    {
        union
        {
            struct {
                int bit0:1;
                int bit1:1;
                int bit2:1;
                int bit3:1;
                int bit4:1;
                int bit5:1;
                int bit6:1;
                int bit7:1;
            };
            unsigned char byte;
        };
    } EigthBits;

    EigthBits b;

    b.byte = 0;
    printf("Will be 0 ==> %d\n", b.byte);

    b.bit4 = 1;
    printf("Will be 16 ==> %d\n", b.byte);
}

この出力を印刷します:

    0 ==> 0 になります
    16になります ==> 16

たとえば、制御レジスタの個々のビットに値を設定すると便利です。必要に応じて、より多くのビット ( などint two_bits:2;) を設定できます。

于 2012-04-10T02:42:31.910 に答える
8

これは珍しいことではありません。たとえば、SDCC (Small Device C Compiler) は、MCS-51 の一般的なコンパイラです。マニュアルはこちらにあります。最も関連性の高いセクションは 3.4.1 で、MCS-51 の言語拡張について説明しています。

3.4.1.6 __ビット

これは、データ型およびストレージ クラス指定子です。変数がビットとして宣言されると、8051 のビット アドレス指定可能メモリに割り当てられます。

 __bit test_bit;

この変数に 1 を書き込むと、アセンブリ コードが生成されます。

 D2*00 setb _test_bit

ビット アドレス指定可能なメモリは、データ メモリの 0x20 から 0x2f に配置される 128 ビットで構成されます。この 8051 固有のストレージ クラスとは別に、ほとんどのアーキテクチャは ANSI-C ビットフィールドをサポートしています4。ISO/IEC 9899 に従って、明示的な符号付き修飾子のないビットおよびビットフィールドは、符号なしとして実装されます。

于 2012-04-10T02:44:12.300 に答える
6

C では、通常、1 バイトを読み取り、必要なビットをマスクしますが、一部のプロセッサ固有のコンパイラでは、レジスタや個々のビットさえも事前定義されています。たとえば、Keil Cx51 ユーザーズ ガイドでは、bitおよびsfrデータ型が定義されています。

sfr次のようなタイプを使用します。

sfr P0 = 0x80;    // Port 0 is accessed at address 80h.
P0 = 0x20;        // Write 20h to Port 0.

バイト単位の方法を使用するには、次のようにします。

#define SFR (* (unsigned char *) 0x80)  // Address of SFR is 0x80.

#define BIT0 0x01  // LSB of any byte
#define BIT1 0x02
#define BIT2 0x04
. . .
#define BIT7 0x80  // MSB of any byte

// Read BIT1 of SFR. sfrBit1 is 1 if BIT1 is set, 0 if not.
unsigned char sfrBit1 = SFR & BIT1  ?  1 : 0;

// Set BIT0 of SFR.
SFR |= BIT0;

// Clear BIT2 of SFR.
SFR &= ~BIT2;

便宜上、個々のビットを設定およびクリアするユーティリティ マクロを定義できます。

#define SET(reg, bit) reg |=  (1 << bit)  // Sets a bit in reg.
#define CLR(reg, bit) reg &= ~(1 << bit)  // Clears a bit in reg.

SET(SFR, 1); // Set BIT1 
CLR(SFR, 2); // Clear BIT2
于 2012-04-10T02:18:15.100 に答える
2

プロセッサ 8051 は、単一ビットをアドレス指定して 0 にクリアする、1 に設定する、または値をテストし、その後にビットが設定またはクリアされた場合に次のコードをバイパスする条件付き分岐を行ういくつかの命令を定義します。

これらの命令は非常に効率的で、2 バイトしか使用しません。最初のバイトは命令を定義し、2 番目のバイトは合計 256 ビットのうち、使用するビットを識別するオペランドです。

最初の 128 ビットは、16 の SFR バイトを参照しています (P0 のアドレス 0x80 のビット 0 から 7、P1 のアドレス 0x88 の SFR のビット 8 から 15、SFR 0xF8 のビット 120 から 127 まで)。

Hans Pasant が前述したように、次の 128 ビットは、0x20 と 0x2F の間の内部 RAM の 16 バイトを参照しています。

8051 は実際にバイト全体を読み取り、テストし、指定されたビットを設定またはクリアし、すべての 8 ビットを同じ場所に書き戻します (テストを除く)。これらの命令は効率的であるだけでなく、R0 ~ R7、アキュムレータなどのレジスタも変更しません。

C コンパイラは、128 を超える "__bit" 変数を簡単に受け入れ、前述の効率的なアセンブラ コードを、ほとんどの人が説明する従来のバイナリ マスキング操作に置き換えることができます。ただし、Keil コンパイラによって実装される最も簡単な解決策は、128 ビットを超える変数を使用する場合にエラーを宣言することです。

指定された数のビットをアドレス指定できる DSP およびグラフィック プロセッサがいくつかあります。これは、効率的な圧縮アルゴリズムや描画ルーチンなどを作成する場合に非常に役立ちます。たとえば、Texas Instruments の TMS34010 では、メモリ アクセスごとに異なるビット数を使用して 2 つのレジスタ グループを定義できます。ループは、たとえば、最初のグループのレジスタを使用して一度に 3 ビットを読み取り、2 番目のグループのレジスタを使用して 11 ビットを書き込むことができます。内部的には、メモリ コントローラは依然として 16 ビットを読み取り、16 ビットを書き戻し、各 16 ビット ワード内の指定された数のビットのみを変更していました。すべてのメモリ操作は、ワードではなくビットを参照しています。たとえば、プログラム カウンタは、各命令の実行時に 16 ずつインクリメントされます。for 下位ビットがゼロ以外の場合、ハードウェアは例外を作成します。

C 言語の発明者は、いつの日かビットアドレス指定可能なプロセッサが登場するだろうと予測しました。彼らは、ビット構造を使用する場合のワード全体の読み取り/書き込みの現在の制限 (Ixe013 で説明されているように) が将来的に解除される可能性があると説明しました。残念ながら、ビット アドレス指定可能なプロセッサは、ソフトウェアの世界ではあまり注目されませんでした。

于 2013-02-04T12:41:52.740 に答える
1

それは、「対処する方法」という意味によって異なります。set_bit(address, bit, value)そのようなアクションを実行するいくつかの,get_bit(address, bit, value)関数を書くことに問題はありません。ただし、少なくともどちらがバイトget_bitかを返します。char

バイト アドレッシングの制限は、ほとんどの最新のコンピューターが使用するハードウェアから自然に発生します。これは、ハード ドライブの 512 バイト セクターに非常に似ており、読み取りまたは書き込みの最小 IO 操作です。ただし、これは単一のバイトとビットの書き込みを止めるものではありません。

于 2012-04-10T02:26:10.680 に答える
1

"C (拡張機能付き)" では何でも可能です。拡張機能付きの C はあらゆる方言であり、空のパイに相当するプログラミングをもたらすからです。

ISO 標準 C では、個別にアドレス指定できる記憶域の最小単位は、文字型で表されるバイトです。

ビット (構造体のビット フィールド メンバーも含む) へのアクセスは、周囲のビットのセル全体にアクセスすることによって実行されます。

プロセッサがビットをアドレス指定できる場合、それに到達する 1 つの方法は、C コンパイラのインライン アセンブリ言語を使用することです。または外部リンクされたアセンブリ言語ルーチン。

于 2012-04-10T02:19:02.587 に答える