UNIX/Linux のデフォルトのワードサイズ

UNIX/Linux のデフォルトのワードサイズ

私はCプログラムの前処理された出力を調べていて、偶然ヘッダーファイルを見ました。wordsize.h

それは /usr/include/i386-linux-gnu/bits/wordsize.h

ファイルにはマクロが1つだけ含まれています

#define __WORDSIZE   32

私の質問は、ワードサイズはインストールされているコンパイラによって決定されるのか、それともインストールした OS (32 ビットまたは 64 ビット) と関係があるのか​​、あるいはマシンのハードウェア構成と関係があるのか​​ということです。

私は Linux での開発は初めてです。

答え1

一般的にwordsizeコンパイル時にターゲット アーキテクチャによって決定されます。コンパイラは通常、wordsize現在のシステムを使用してコンパイルします。

(他にも)さまざまなフラグを使用gccしてこれを調整することもできます。たとえば、64ビットホストでは、32ビット機械、または32 ビットワード。

-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


クロスコンパイルについては、マルチライブラリSO 上の 32 ビット リンク) をクリックしてウェブを検索します。

GCC がどのフラグでビルドされたかを確認するには、次の操作を行います。

gcc -v

サイズに関しては、通常、中央処理装置と密接に関連しており、メモリ アドレスの最大サイズ、CPU レジスタのサイズなどが関連しています。

ざっと見る分には、これについて多くを理解する必要はありませんが、あなたがどこにいるかそれはいくつかの洞察を与えることができます:

フラグgccを使用してコンパイルすると、-S組立説明ここで少し混乱しますが、たとえば 32 ビット マシンでは、ワードは 16 ビットで、long は 32 ビットです。( __WORDSIZE)

つまり、例えば、movl $123, %eax移動はlong(32ビット__WORDSIZE)を意味します。123 eax登録するためにmovwワード(16 ビット)を移動することを意味します。


これは命名規則であり、WORDSIZE複数の意味を持つ可能性があるとだけ言っておきます。また、次のような定義をしているコードに遭遇することもあります。

#define WORD_SIZE 16

すべてはコンテキストに依存するためです。ソースのワード サイズが 16 ビットであるファイルまたはストリームからデータを読み取る場合、これは自然なことです。__WORDSIZEコードで読み取るときに、常にワード サイズを意味するとは限らないことを指摘しておきます。


ユーザ定義の例は、WORD_SIZE生成されたマシンコードの命令セットには影響しません。GCC全般については、この本(残念ながら少し古いですが、同様の読みやすい最新の本はまだ見つかっていません。(それほど一生懸命探したわけではありませんが。) 短く、簡潔で、わかりやすい内容です。また、機能の追加など、変更されている可能性があることを念頭に置いておけば、それでも良い紹介になります。)

コンパイル時のさまざまな側面について、簡潔かつわかりやすく紹介しています。第11章コンパイルチェーンのわかりやすい説明。


GCC で 16 ビットをコンパイルするオプションは知りません。 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。このコードは、次の段階のファイルが存在する場所を特定し、それらをメモリにロードして実行を続行し、最後に入力します。 保護モードあなたが持っている普通32 ビット モード。

答え2

私のものは次のとおりです:

% 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コンパイラに付属する によって決定されます。ただし、インテリジェントなコンパイラは適切なサイズを選択します。

答え3

-m32通常は、またはオプションのいずれかを使用して、コンパイル時にデフォルトのワード サイズを選択できるはずです-m64

/usr/include/i386-linux-gnu/bits/wordsize.h32 ビット アプリケーションをコンパイルするときに使用するように設計されています。

/usr/include/x86_64-linux-gnu/bits/wordsize.h64 ビット定義を含むが必要です__WORDSIZE

この変更は Ubuntu 11.4 で導入されました:https://wiki.ubuntu.com/マルチアーキテクチャスペック

失敗した場合は-m64、32 ビット ディストリビューションを使用している可能性があります。uname -mお知らせします。

32 ビット システムで 64 ビット バイナリをクロスコンパイルすることは可能ですが、32 ビット システムでそれを実行する簡単な方法がないため不便です。

CPU が 64 ビット モデルの場合 ( で確認lscpu)、マルチアーキテクチャ パッケージを簡単にビルドできるように 64 ビット ディストリビューションをインストールすることをお勧めします。

関連情報