【发布时间】:2011-03-05 14:04:32
【问题描述】:
非常简单的问题,我读到 GCC 支持 long long int 类型。但是,当 CPU 只有 32 位宽时,如何用它进行数学运算呢?
【问题讨论】:
非常简单的问题,我读到 GCC 支持 long long int 类型。但是,当 CPU 只有 32 位宽时,如何用它进行数学运算呢?
【问题讨论】:
编译器将综合使用多条 CPU 指令来执行运算的数学运算(或使用函数调用)。例如,添加操作将添加 long long 值的低位组件(低位字),然后将该操作的进位输入到 long long 的高位字上的添加操作中.
所以下面的C代码:
long long a;
long long b;
long long c;
// ...
c = a + b;
可能由如下所示的指令序列表示:
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
如果您考虑一下,早在long long 出现之前,8 位和 16 位系统的编译器就必须对 16 位和/或 32 位值执行此类操作。
【讨论】:
在内部,类型由高位字和低位字表示,如:
struct long
{
int32 highWord;
uint32_t lowWord;
}
编译器需要知道它是 32 位还是 64 位环境,然后选择正确的数字表示 - 如果是 64 位,则可以原生完成,如果是 32 位,编译器必须处理高/低字之间的数学运算。
如果您查看 math.h,您可以看到用于此的函数,并自己使用它们。另外,请注意 little-endian 和 big-endian (see wiki) 之间的区别,具体用法取决于操作系统。
【讨论】:
lowByte 真的是uint32_t :-P
说架构是 32 位(或 64 位或其他)通常只是处理器能力的近似值。通常你只指具有该数字的指针的宽度,算术可能会完全不同。例如,x86 架构有 32 位指针,大多数算术运算是在 32 位寄存器中执行的,但它也原生支持一些基本的 64 位操作。
此外,您不应认为标准整数类型具有一定的规定宽度。特别是 long long 至少为 64 位,但可能更宽。如果您想确定宽度,请使用 typedefs int32_t, int64_t。
如果您想知道 gcc(或任何其他编译器)对 long long 的作用,您必须查看特定目标平台的规范
【讨论】:
如果您有可访问的 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
【讨论】:
最有可能作为一个班级,而不是本机。任何编译器都可以/可以支持任何大数字集的方式相同。
【讨论】: