我正在检查 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.h
并inttypes.h
了解此定义的用法。
对于交叉编译检查多库(SO 上的 32 位链接)并搜索网络。
检查您的 GCC 是使用哪些标志构建的:
gcc -v
至于大小,它们通常与中央处理器密切相关——例如内存地址的最大大小、CPU寄存器的大小等。
为了快速浏览,您不需要了解太多,但取决于你在哪里它可以提供一些见解:
如果您使用gcc
该标志并进行编译,-S
您还可以查看组装说明。这里,有点令人困惑,例如在 32 位机器上,一个字是 16 位,而长是 32 位。 ( __WORDSIZE
)
因此,egmovl $123, %eax
表示长移(32 位 - __WORDSIZE
)123
注册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 位发行版以便能够轻松构建多架构包。