UNIX/Linux 中的默认字长

Aru*_*mar 7 osx programming c cpu-architecture

我正在检查我的 C 程序的预处理输出,碰巧查看了头文件 wordsize.h

它位于 /usr/include/i386-linux-gnu/bits/wordsize.h

该文件只包含一个宏

#define __WORDSIZE   32
Run Code Online (Sandbox Code Playgroud)

我的问题是,字长是由安装的编译器决定的,还是与我安装的操作系统(32 位或 64 位)有关,还是与我的硬件配置有关?机器。

我是 Linux 下的开发新手。

Run*_*ium 8

一般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.
Run Code Online (Sandbox Code Playgroud)

您还应该查看limits.hinttypes.h了解此定义的用法。


对于交叉编译,请查看multilibSO 上的 32 位链接)并搜索网络。

通过以下方式检查您的 GCC 是用哪些标志构建的:

gcc -v
Run Code Online (Sandbox Code Playgroud)

至于大小,它们通常与中央处理单元密切相关,例如内存地址的最大大小、CPU 寄存器的大小等。

快速浏览一下,您不需要了解太多内容,但根据您所在的位置,它可以提供一些见解:

如果您使用gcc和编译-S标志,您还可以查看汇编指令。在这里,有点令人困惑,例如在 32 位机器上,一个字是 16 位,而 long 是 32 位。( __WORDSIZE)

所以 egmovl $123, %eax意味着将 long (32-bit - __WORDSIZE)移动123 eaxregistermovw意味着移动 word (16-bit)。


这是命名约定,只是说这WORDSIZE可能意味着不止一件事。您还可以遇到代码,例如,它们定义了类似的东西

#define WORD_SIZE 16
Run Code Online (Sandbox Code Playgroud)

因为这一切都取决于上下文。如果您从源字长为 16 位的文件或流中读取数据,这将是很自然的。只是要指出,__WORDSIZE在代码中阅读时不要总是假设字大小。


用户定义的示例WORD_SIZE不会影响生成的机器代码中的指令集。对于一般的 GCC,我会推荐这本书(不幸的是,它有点旧了——但还没有找到一本类似的易于阅读的最新书。(并不是我看起来那么努力。)它简短、简洁和甜蜜。如果你只记住这一点事情可能会发生变化,例如添加的功能等,但它提供了很好的介绍。)

它在编译时快速而漂亮地介绍了各个方面。查看第 11 章以获得一个很好的编译链解释。


我不知道 GCC 中有什么选项可以编译 16 位。一种方法是在汇编中编写.code16用于指示代码应该是 16 位的。

例子:

    .file "hello.s"
    .text
    .code16            /* Tel GAS to use 16-bit instructions. */
.globl start, _start
start:
_start:
    movb $0x48, %al
        ...
Run Code Online (Sandbox Code Playgroud)

例如,引导加载程序(如 GRUB 和 LILO)需要它来处理MBR硬盘驱动器上的代码。

这样做的原因是,当您的计算机启动时,CPU 处于特殊模式,它没有 32 位但最多 16 位指令,也就是 实模式

简而言之,BIOS 进行硬件测试,然后将启动磁盘的前 512 字节加载到内存中,并将控制权交给从地址开始的代码0。这段代码依次定位下一阶段文件所在的位置,将它们加载到内存中并继续执行,最后进入 保护模式,您拥有正常的32 位模式。


bah*_*mat 5

这是我的:

% 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
Run Code Online (Sandbox Code Playgroud)

所以它是wordsize.h由编译器附带的 决定的。但聪明的人会选择合适的尺寸。