Cプログラムの前処理された出力を調べていて、たまたまヘッダーファイルwordsize.h
を調べていました。
/usr/include/i386-linux-gnu/bits/wordsize.h
にあります
ファイルにはマクロが1つだけ含まれています
#define __WORDSIZE 32
私の質問は、ワードサイズはインストールされているコンパイラによって決定されるのか、それともインストールしたOS(32ビットまたは64ビット)と関係があるのか、それとも私のハードウェア構成と関係があるのかということです。機械。
Linuxでの開発は初めてです。
一般に、 wordsize
は、コンパイル時にターゲットアーキテクチャに基づいて決定されます。コンパイラは通常、現在のシステムではwordsize
を使用してコンパイルします。
gcc
(とりわけ)を使用して、さまざまなフラグを使用してこれを調整することもできます。例えば。 64ビットホストでは、 2ビット マシン、またはforce32ビットワード用にコンパイルできます。
-m32 # int, long and pointer to 32 bits, generates code for i386.
-m64 # int, long and pointer to 64 bits, generates code for x86-64.
-mx32 # int, long and pointer to 32 bits, generates code for x86-64.
この定義の使用法を確認するには、limits.h
およびinttypes.h
も確認する必要があります。
クロスコンパイルについては、 multilib (SOの32ビットリンク)をチェックアウトし、Webを検索してください。
GCCが作成されたフラグを確認してください。
gcc -v
サイズに関しては、通常、中央処理装置と密接に関連しており、メモリアドレスの最大サイズ、CPUレジスタのサイズなどに関連しています。
簡単に垣間見るために、これの多くを理解する必要はありませんが、どこにいるかに応じて、いくつかの洞察を得ることができます:
gcc
を使用し、-S
フラグを使用してコンパイルする場合は、 アセンブリ命令 も確認できます。ここでは、少し紛らわしいです。 32ビットマシンWordは16ビットで、longは32ビットです。 (__WORDSIZE
)
だから例えばmovl $123, %eax
は長く移動することを意味します(32ビット-__WORDSIZE
)123
eax
レジスタに 、movw
はWordを移動することを意味します(16ビット)。
これは命名規則です–そしてWORDSIZE
は複数のことを意味する可能性があると言うだけです。また、コードに出くわすこともできます。次のようなものを定義します
#define Word_SIZE 16
それはすべてコンテキストに依存するためです。ソースのワードサイズが16ビットのファイルまたはストリームからデータを読み取る場合、これは自然なことです。コードで読み取るときに、ワードサイズが__WORDSIZE
を意味するとは限らないことを指摘するだけです。
ユーザー定義のWord_SIZE
の例は、生成されたマシンコードの命令セットに影響を与えません。 GCC全般については、 この本 をお勧めします。 (残念ながら少し古いですが、同じような読みやすい最新の本はまだ見つかりません。(私はそれほど一生懸命見ていないわけではありません。)短く、簡潔で、甘いです。 。そして、機能の追加など、物事が変更された可能性があることだけを念頭に置いておくと、それでもなお良い紹介になります。)
コンパイル時にさまざまな側面をすばやく簡単に紹介します。ニースのコンパイルチェーンの説明については、 第11章 を参照してください。
16ビットをコンパイルするためのGCCのオプションを知りません。これを行う1つの方法は、.code16
を使用してアセンブリで記述し、コードが16ビットであることを指示することです。
例:
.file "hello.s"
.text
.code16 /* Tel GAS to use 16-bit instructions. */
.globl start, _start
start:
_start:
movb $0x48, %al
...
これは、例えばによって必要とされます。ハードドライブのMBR
にあるコードのGRUBやLILOなどのブートローダー。
この理由は、コンピュータが起動すると、CPUが特別なモードになり、32ビットではなく最大16ビットの命令が発生するためです。別名 リアルモード 。
つまり、BIOSがハードウェアテストを実行してから、ブートディスクの最初の512バイトをメモリにロードし、アドレス0
で始まるコードに制御を任せます。このコードは、ファイルの次のステージが存在する場所を特定し、これらをメモリにロードして実行を継続し、最後に プロテクトモードnormal32ビットモードがあります。
これが私の持っているものです:
% cat /usr/include/bits/wordsize.h
/* Determine the wordsize from the preprocessor defines. */
#if defined __x86_64__
# define __WORDSIZE 64
# define __WORDSIZE_COMPAT32 1
#else
# define __WORDSIZE 32
#endif
したがって、コンパイラに付属しているwordsize.h
によって決定されます。しかし、インテリジェントなものは適切なサイズを選択します。
通常、-m32
または-m64
オプションのいずれかを使用して、コンパイル時にデフォルトのワードサイズを選択できるはずです。
/usr/include/i386-linux-gnu/bits/wordsize.h
は、32ビットアプリケーションをコンパイルするときに使用するように設計されています。
64ビットの/usr/include/x86_64-linux-gnu/bits/wordsize.h
定義を含む__WORDSIZE
が必要です。
この変更はUbuntu11.4で導入されました: https://wiki.ubuntu.com/MultiarchSpec
-m64
が失敗した場合、32ビットの配布がある可能性があります。 uname -m
が教えてくれます。
32ビットシステムで64ビットバイナリをクロスコンパイルすることは可能ですが、そこで実行する簡単な方法がないため、不便です。
CPUが64ビットモデルの場合(lscpu
で確認)、マルチアーチパッケージを簡単に構築できるように64ビットディストリビューションをインストールすることをお勧めします。