UNIX/Linux 中的默认字长

UNIX/Linux 中的默认字长

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

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

该文件仅包含一个宏

#define __WORDSIZE   32

我的问题是,字长是由安装的编译器决定的,还是与我安装的操作系统(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.hinttypes.h了解此定义的用法。


对于交叉编译检查多库SO 上的 32 位链接)并搜索网络。

检查您的 GCC 是使用哪些标志构建的:

gcc -v

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

为了快速浏览,您不需要了解太多,但取决于你在哪里它可以提供一些见解:

如果您使用gcc该标志并进行编译,-S您还可以查看组装说明。这里,有点令人困惑,例如在 32 位机器上,一个字是 16 位,而长是 32 位。 ( __WORDSIZE)

因此,egmovl $123, %eax表示长移(32 位 - __WORDSIZE123 注册eax、 和movw表示移动字(16 位)。


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

#define WORD_SIZE 16

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


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

它对编译时的各个方面进行了快速而精彩的介绍。看着第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
        ...

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

原因是,当您的计算机启动时,CPU 处于特殊模式,其中没有 32 位指令,但最多有 16 位指令(AKA) 实模式

简而言之,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.h设计用于编译 32 位应用程序时使用。

应该有一个/usr/include/x86_64-linux-gnu/bits/wordsize.h包含 64 位__WORDSIZE定义的文件。

此更改是在 Ubuntu 11.4 中引入的:https://wiki.ubuntu.com/MultiarchSpec

如果-m64失败,您可能拥有 32 位发行版。uname -m会告诉你的。

虽然可以在 32 位系统上交叉编译 64 位二进制文​​件,但这会很不方便,因为您没有任何简单的方法来运行它们。

如果您的 CPU 是 64 位型号(使用 进行检查lscpu),您可能需要安装 64 位发行版以便能够轻松构建多架构包。

相关内容