在32位架构的最低级别上如何实现64位类型和操作? [英] How are the 64-bit types and operations implemented on the lowest level on a 32-bit architecture?

查看:151
本文介绍了在32位架构的最低级别上如何实现64位类型和操作?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何在最低的汇编层级实现类似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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆