32位机器上的long long int

非常简单的问题,我读到GCC支持long long int类型。 但是,当CPU仅为32位宽时,如何使用它进行数学运算?

编译器将合成使用多个CPU指令执行操作的数学运算(或使用函数调用)。 例如,添加操作将添加long long值的低阶分量(低字),然后执行该操作并将其馈送到long long高阶字上的add操作。

所以下面的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 

如果你考虑一下,8和16位系统的编译器必须在很久以前就已经为16和/或32位值做了这种类型的事情。

在内部,类型由高字和低字表示,如:

 struct long { int32 highWord; uint32_t lowWord; } 

编译器需要知道它是32位还是64位环境然后选择正确的数字重新定位 – 如果它是64位,它可以本机完成,如果是32位,编译器必须处理数学之间的数学运算。高/ lowword。

如果你看看math.h,你可以看到用于此的函数,并自己使用它们。 另外需要注意的是,请注意little-endian和big-endian( 请参阅wiki )之间的区别,用法取决于操作系统。

说架构是32位(或64或其他)通常只是处理器能够的近似值。 通常你只引用带有该数字的指针的宽度,算术可能会大不相同。 例如,x86架构有32位指针,大多数算术在32位寄存器中执行,但它也支持一些基本的64位操作。

此外,您不应该遵循标准整数类型具有一定规定宽度的印象。 特别是长长度至少为64位但可能更宽。 如果您想要可移植地确定宽度,请使用typedefs int32_t,int64_t。

如果你想知道gcc(或任何其他编译器)长期做什么,你必须查看你的特定目标平台的规范

如果您可以访问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 // ab subl %ecx, %eax sbbl %ebx, %edx // etc 

最有可能是作为一个阶级,而不是本地的。 任何编译器都可以/可以支持任何大数集的方式相同。