web-dev-qa-db-ja.com

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

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

/usr/include/i386-linux-gnu/bits/wordsize.hにあります

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

#define __WORDSIZE   32

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

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

5
ArunMKumar

一般に、 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も確認する必要があります。


クロスコンパイルについては、 multilibSOの32ビットリンク)をチェックアウトし、Webを検索してください。

GCCが作成されたフラグを確認してください。

gcc -v

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

簡単に垣間見るために、これの多くを理解する必要はありませんが、どこにいるかに応じて、いくつかの洞察を得ることができます:

gccを使用し、-Sフラグを使用してコンパイルする場合は、 アセンブリ命令 も確認できます。ここでは、少し紛らわしいです。 32ビットマシンWordは16ビットで、longは32ビットです。 (__WORDSIZE

だから例えばmovl $123, %eaxは長く移動することを意味します(32ビット-__WORDSIZE123eaxレジスタに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ビットモードがあります。

6
Runium

これが私の持っているものです:

% 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
bahamat

通常、-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ビットディストリビューションをインストールすることをお勧めします。

2
jlliagre