如何在 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 位数据类型相比,使用这些类型的计算必须有相当大的开销。
提前感谢您和问候
你是对的,当你编译 32 位体系结构的代码时,你必须使用 32 位操作数模拟 64 位操作数和操作。
一个8字节的变量(uint64_t
只是long long
的typedef)存储在2个4字节寄存器中。
对于加法(和减法),您必须首先添加较低的 4 个字节,然后在较高的 4 个字节上执行第二次加法(或借用减法)。由于第二个添加也添加了第一个添加的进位,因此结果是正确的。加减的开销不大。
然而,对于乘法和除法,事情并没有那么简单。通常调用例程来执行此类操作,并且开销要大得多。
让我们以这个简单的 c 代码为例:
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生成的程序集,我们可以看到:
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 位位置。
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
指令执行求和,然后对较高的 32 位使用adc
(加进位)执行总和。减法类似:第二个运算是sbb
(借用减法)。
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
产品和除法是通过调用特殊例程来执行的。
相关文章:
- 使用简单类型列表实现的指数编译时间.为什么
- 实现有界基元类型的c++
- 根据C++标准的定义实现"is_similar"类型特征
- 为什么 std::lerp 不适用于任何已实现所需操作的类型?
- C ++类型特征:确保子类实现方法
- 为自定义打印调试实现传递任何类型的变量
- 为 Sql 服务器实现 odbc 包装器.将数据库数据读取为字符或要求驱动程序将数据转换为 C 类型
- 将C++子类成员函数(虚拟实现)传递给 C 类型函数指针
- 使用智能指针指向 C 库中的结构,该结构通过 typedef 隐藏实现(即不完整的类型)
- 在 OpenCL 内核中实现半精度浮点数据类型
- 在头文件中使用opencv类型来实现未定义的标识符
- 如何实现对参数顺序不可知的std::same_as的广义形式(即对于两个以上的类型参数)
- 如何实现一个接受任何容器类型的函数
- 有没有一种方法可以使用SFINAE来检测一个类型是否实现了给定的抽象基类
- 实现类型类向量的元素
- 如何在 python 中实现 c++ 类型结构
- 我能否在 uint_fast64_t 和无符号长整型之间实现类型等效性
- 从Bloch的Effective Java in C++实现类型安全的异构容器(VS2010)
- SFINAE使用模板、专门化和实现类型擦除
- 使用的实现类型