非常简单的问题,我读到GCC支持long long int类型。但是,当CPU只有32位宽时,如何用它进行数学运算呢?
答案 0 :(得分:20)
编译器将合成使用多个CPU指令执行操作的数学运算(或使用函数调用)。例如,添加操作将添加long long
值的低阶组件(低字),然后执行该操作并将其输入到{的高位字的添加操作中{1}}。
以下C代码:
long long
可能由类似于:
的指令序列表示long long a;
long long b;
long long c;
// ...
c = a + b;
如果你考虑一下,8位和16位系统的编译器必须在mov eax, [a.low] ; add the low order words
add eax, [b.low]
mov edx, [a.high] ; add the high order words,
adc edx, [b.high] ; including the carry
mov [c.low], eax
mov [c.high], edx
出现之前很久就为16位和/或32位值做这种类型的事情。
答案 1 :(得分:9)
在内部,类型由高字和低字表示,如:
struct long
{
int32 highWord;
uint32_t lowWord;
}
编译器需要知道它是32位还是64位环境,然后选择正确的数字重新定位 - 如果它是64位,它可以本机完成,如果它是32位,编译器必须处理高/低位之间的数学。
如果您查看math.h,可以看到用于此的函数,并自己使用它们。另请注意,请注意little-endian和big-endian(see wiki)之间的区别,用法取决于操作系统。
答案 2 :(得分:2)
说一个架构是32位(或64或其他)通常只是处理器能够的近似值。通常你只引用带有该数字的指针的宽度,算术可能会有很大不同。例如,x86架构有32位指针,大多数算术在32位寄存器中执行,但它也支持一些基本的64位操作。
此外,您不应该遵循标准整数类型具有一定规定宽度的印象。特别是long long至少为64位但可能更宽。如果您想要可移植地确定宽度,请使用typedefs int32_t,int64_t。
如果你想知道gcc(或任何其他编译器)长期做什么,你必须查看特定目标平台的规范
答案 3 :(得分:2)
如果您可以访问32位系统,那么编译和测试就很容易了。 gcc有一个标志-S
,它打开汇编语言输出。这是我在32位英特尔上产生的内容:
// read two long longs from stack into eax:edx and ecx:ebx
movl 32(%esp), %eax
movl 36(%esp), %edx
movl 24(%esp), %ecx
movl 28(%esp), %ebx
// a+b
addl %ecx, %eax
adcl %ebx, %edx
// a-b
subl %ecx, %eax
sbbl %ebx, %edx
// etc
答案 4 :(得分:1)
最有可能是作为一个班级,而不是本地人。任何编译器都可以/可以支持任何大数集的方式相同。