10

私の理解が正しければ、0x10c のDCPU-16 仕様はのほとんどのメモリ アーキテクチャのようにバイトではなく、各オフセットが 16 ビット ワードをアドレス指定する 16 ビット アドレス空間を記述しています。これにはいくつかの奇妙な結果があります。sizeof(char)sizeof(short)1

このような異なるメモリ アドレッシング スキーム間で C コードの移植性を維持することは可能ですか? 覚えておくべき落とし穴は何ですか?

編集:おそらく、より具体的な例を挙げるべきでした。バイト ストリームを処理するネットワーク コードがあるとします。コードを同じままにできるように、各アドレスに 1 バイトだけを配置してメモリの半分を破棄しますか?それとも、オフセットごとに N バイトを処理するためにビットシフトですべてを一般化しますか?

edit2:答えはデータ型のサイズの問題に焦点を当てているようですが、それは重要ではありませんでした-言及するべきではありませんでした。問題は、ポインタを使用してメモリ内の任意のバイトをアドレス指定できなくなったことにどう対処するかということです。コードがこれにとらわれないことを期待するのは合理的ですか?

4

4 に答える 4

9

それは完全に実現可能です。大まかに言えば、C の基本的な整数データ型のサイズは次のとおりです。

sizeof (char) <= sizeof (short) <= sizeof (int) <= sizeof (long)

上記は仕様が正確に述べているものではありませんが、それに近いものです。

コメントで awoodland が指摘したように、DCPU-16 の C コンパイラにはCHAR_BIT == 16.

DCPU-16 がsizeof (char) == 2.

于 2012-04-11T14:43:20.400 に答える
6

「バイトをアドレス指定する機能が失われる」と言うときは、「char」ではなく「bit-octet」を意味すると思います。ポータブルコードは、のみを想定する必要がありCHAR_BIT >= 8ます。実際には、バイトアドレス指定を持たないアーキテクチャは、多くの場合CHAR_BIT == 8、を定義し、コンパイラにバイトにアクセスするための命令を生成させます。

私は実際に提案する答えに同意しません:CHAR_BIT == 16良い選択として。私は好む:CHAR_BIT == 8、とsizeof(short) == 2。この場合、コンパイラは、多くのRISCアーキテクチャの場合と同様に、バイトアクセスのシフト/マスキングを処理できます。

NotchがDCPU-16の仕様をさらに改訂し、明確にすることを想像しています。すでに割り込みメカニズムの要求とさらなる指示があります。これはゲームの美的背景であるため、公式のABI仕様がまもなく発表されるとは思えません。そうは言っても、誰かがそれに取り組んでいるでしょう!

編集:

Cの配列を考えてみましょうchar。コンパイラは、ネイティブの16ビットwordのDCPUメモリごとに2バイトをパックします。したがって、たとえば10番目の要素(index 9)にアクセスする場合は、単語#[9/2] = 4をフェッチし、バイト#[9%2]=1を抽出します。

'X'を配列の開始アドレス、'I'をインデックスとします。

SET J, I
SHR J, 1    ; J = I / 2
ADD J, X    ; J holds word address
SET A, [J]  ; A holds word
AND I, 0x1  ; I = I % 2 {0 or 1}
MUL I, 8    ; I = {0 or 8} ; could use: SHL I, 3
SHR A, I    ; right shift by I bits for hi or lo byte.

レジスタAは「バイト」を保持します。これは16ビットレジスタであるため、上半分は無視できます。または、上半分をゼロにすることもできます。

AND A, 0xff ; mask lo byte.

これは最適化されていませんが、アイデアを伝えています。

于 2012-04-11T19:58:20.547 に答える
0

はい、Cコードを移植することは完全に可能です

データ転送に関しては、ビットをパックする (または圧縮を使用する) か、16 ビット バイトで送信することをお勧めします。

CPU はほぼ完全に (ゲームの) 内部デバイスとのみ通信するため、これもすべて 16 ビットである可能性が高く、これは実際の問題ではありません。

CHAR_BITところで、(IIRC)各文字はアドレス指定可能でなければならないので、16にする必要があることCHAR_BIT ==8に同意しsizeof(char*) ==2ます。

于 2012-04-11T20:08:44.407 に答える
0

等式は次のようになります。

1 == sizeof(char) <= sizeof(short) <= sizeof(int) <= sizeof(long)

shortタイプは である可能性があり、実際のところ、タイプが実際にあまりにも多く1なりたいと思うかもしれません(私は仕様を読んでいませんが、通常のデータ型は 16 ビットであると想定しています)。このようなものは、コンパイラによって定義されます。int1

実際には、コンパイラーは、コンパイラーが追加の作業 (ソフトウェアでの加算/乗算などの実装など) を行う必要がある場合でも、longより大きな値に設定することをお勧めします。int

これはメモリ アドレスの問題ではなく、粒度の問題です。

于 2012-04-11T18:00:43.757 に答える