在32位架构的最低级别上如何实现64位类型和操作? [英] How are the 64-bit types and operations implemented on the lowest level on a 32-bit architecture?
问题描述
如何在最低的汇编层级实现类似int64_t的类型?我使用32位机器,仍然可以使用int64_t为例。我的初始假设是64位只是模拟,因此,当在32位机器上时,与32位数据类型相比,这些类型的计算必须有相当一些开销。
How are types like int64_t implemented on the lowest i.e. assembly level? I'm using a 32 bit machine and still can use int64_t for example. My initial assumption is that the 64 bit are just simulated and thus there must be quite some overhead for computation with these types in comparison with 32 bit data types when being on a 32 bit machine.
提前感谢您,并谨慎
推荐答案
您说得对,当您编译32位架构的代码时,使用32位操作数来模拟64位操作数和操作。
You are right, when you compile code for 32 bit architectures, you have to simulate 64 bit operands and operations using 32 bit operands.
一个8字节变量( uint64_t
long long
的typedef存储在2个4字节寄存器中。
An 8-byte variable (uint64_t
which is just a typedef for long long
) is stored in 2 4-byte registers.
您必须先添加较低的4个字节,然后在较高的4个字节上执行第二个 with carry (或减去借用)。由于第二次添加还添加了第一次添加的进位,结果是正确的。
For adding (and subtracting), you have to first add the lower 4 bytes and then perform a second add with carry (or a subtract with borrow) on the higher 4 bytes. Since the second add also adds the carry from the first add, the result is correct. The overhead for adding and subtracting is not much.
对于乘法和除法,事情并不那么简单。通常,调用一个例程来执行这些操作,并且开销显着更大。
For multiplying and division however, things aren't that simple. Usually a routine is called to perform these kind of operations, and the overhead is significantly bigger.
代码:
int main() {
long long a = 0x0102030405060708;
long long b = 0xA1A2A3A4A5A6A7A8;
long long c = 0xB1B2B3B4B5B6B7B8;
c = a + b;
c = a - b;
c = a * b;
c = a / b;
return 0;
}
分析MSVC生成的程序集,我们可以看到:
Analyzing the assembly generated by MSVC we can see:
2: long long a = 0x0102030405060708;
012D13DE mov dword ptr [a],5060708h
012D13E5 mov dword ptr [ebp-8],1020304h
3: long long b = 0xA1A2A3A4A5A6A7A8;
012D13EC mov dword ptr [b],0A5A6A7A8h
012D13F3 mov dword ptr [ebp-18h],0A1A2A3A4h
4: long long c = 0xB1B2B3B4B5B6B7B8;
012D13FA mov dword ptr [c],0B5B6B7B8h
012D1401 mov dword ptr [ebp-28h],0B1B2B3B4h
64位变量分为2个32位位置。
a 64 bit variable is split in 2 32-bit locations.
6: c = a + b;
012D1408 mov eax,dword ptr [a]
012D140B add eax,dword ptr [b]
012D140E mov ecx,dword ptr [ebp-8]
012D1411 adc ecx,dword ptr [ebp-18h]
012D1414 mov dword ptr [c],eax
012D1417 mov dword ptr [ebp-28h],ecx
7: c = a - b;
012D141A mov eax,dword ptr [a]
012D141D sub eax,dword ptr [b]
012D1420 mov ecx,dword ptr [ebp-8]
012D1423 sbb ecx,dword ptr [ebp-18h]
012D1426 mov dword ptr [c],eax
012D1429 mov dword ptr [ebp-28h],ecx
在低32位上使用 add
指令执行总和,然后使用 adc
(加上进位)用于高32位。减法类似:第二个操作是 sbb
(减去借位)。
a sum is performed with an add
instruction on the lower 32 bits and then with an adc
(add with carry) for the higher 32 bits. Subtraction is similar: the second operation is sbb
(subtract with borrow).
8: c = a * b;
012D142C mov eax,dword ptr [ebp-18h]
012D142F push eax
012D1430 mov ecx,dword ptr [b]
012D1433 push ecx
012D1434 mov edx,dword ptr [ebp-8]
012D1437 push edx
012D1438 mov eax,dword ptr [a]
012D143B push eax
012D143C call __allmul (012D105Ah)
012D1441 mov dword ptr [c],eax
012D1444 mov dword ptr [ebp-28h],edx
9: c = a / b;
012D1447 mov eax,dword ptr [ebp-18h]
012D144A push eax
012D144B mov ecx,dword ptr [b]
012D144E push ecx
012D144F mov edx,dword ptr [ebp-8]
012D1452 push edx
012D1453 mov eax,dword ptr [a]
012D1456 push eax
012D1457 call __alldiv (012D1078h)
012D145C mov dword ptr [c],eax
012D145F mov dword ptr [ebp-28h],edx
通过调用特殊例程来执行乘积和除法。
The product and division are performed by calling special routines.
这篇关于在32位架构的最低级别上如何实现64位类型和操作?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!