0

我们针对 OS X 上 Clang 下的一些 X32 代码进行了错误报告(错误如下所示)。用户尝试在 Intel x86_64 系统上使用-arch i386. X32 是 32 位整数、长整数和指针

根据System V Application Binary Interface, AMD64 (With LP64 and ILP32 Programming Models) (page 104),有效的配置要么__ILP32__单独,要么__ILP32____x86_64__(和朋友一样amd64,代替__x86_64__)。

我还查了SYSTEM V APPLICATION BINARY INTERFACE for Intel386,也没有提到__ILP32__和朋友。所以我认为不__ILP32__应该出现在纯 32 位系统上。

我认为以上内容应该足以回答这个问题,但我在 OS X 系统上使用 Clang。OS X ABI 函数调用指南没有讨论它,并且经常遵循 System V 指南。但是,引用的 System V 指南来自 2003 年,早于 X32,因此没有处理。

我的问题是,是__ILP32____i386__一个有效的组合或配置?


为了完整起见,这里是代码和编译器错误。我不是试图解决这个问题。

源代码

BOOL_X32在环境中定义时__ILP32__定义。

asm volatile
(
    // save ebx in case -fPIC is being used
# if BOOL_X32 || BOOL_X64
    "pushq %%rbx; cpuid; mov %%ebx, %%edi; popq %%rbx"
# else // BOOL_X86
    "push %%ebx; cpuid; mov %%ebx, %%edi; pop %%ebx"
# endif
    : "=a" (output[0]), "=D" (output[1]), "=c" (output[2]), "=d" (output[3])
    : "a" (input), "c" (0)
);

编译器错误

X32主要是32 位的。但是,当使用汇编语言与堆栈交互时,我们需要推送/弹出 64 位寄存器和值。

$ make cpu.o
clang++ -DNDEBUG -g2 -O2 -arch i386 -fPIC -pipe -c cpu.cpp
cpu.cpp:104:4: error: register %rbx is only available in 64-bit mode
                        "pushq %%rbx; cpuid; mov %%ebx, %%edi; popq %%rbx"
                        ^
<inline asm>:1:8: note: instantiated into assembly here
        pushq %rbx; cpuid; mov %ebx, %edi; popq %rbx
              ^~~~~
cpu.cpp:104:4: error: register %rbx is only available in 64-bit mode
                        "pushq %%rbx; cpuid; mov %%ebx, %%edi; popq %%rbx"
                        ^
<inline asm>:1:42: note: instantiated into assembly here
        pushq %rbx; cpuid; mov %ebx, %edi; popq %rbx
                                                ^~~~
2 errors generated.

-arch i386最后,这是在 x86_64 系统上使用时 Clang 的预处理器宏:

$ clang++ -arch i386 -dM -E - < /dev/null | egrep -i "(86|64|ilp)"
#define _ILP32 1
#define __ILP32__ 1
...
#define __i386 1
#define __i386__ 1
#define i386 1
4

1 回答 1

2

是的,__i386__with__ILP32__是一个完全有效的配置。这意味着您正在编译器上为 32 位 x86 构建代码,其中intlong和 指针是 32 位宽。

虽然像“ILP32”这样的数据模型名称通常用于描述 64 位系统,但使用这样的名称,或存在与之相关的宏,对指令集毫无意义。虽然 System V ABI 没有声明这个宏应该出现在 32 位系统上,但它也没有声明它一定不能出现!

无论如何。如果您需要确定正在使用的指令集,请使用__i386__and __x86_64__; 这就是他们的目的。

于 2015-12-01T04:03:46.790 回答