Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>You are right, when you compile code for 32 bit architectures, you have to simulate 64 bit operands and operations using 32 bit operands.</p> <p>An 8-byte variable (<code>uint64_t</code> which is just a typedef for <code>long long</code>) is stored in 2 4-byte registers.</p> <p>For adding (and subtracting), you have to first add the lower 4 bytes and then perform a second add <strong>with carry</strong> (or a subtract <strong>with borrow</strong>) 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.</p> <p>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.</p> <hr> <p>Lets take this simple c code:</p> <pre><code>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; } </code></pre> <p>Analyzing the assembly generated by MSVC we can see:</p> <hr> <pre><code> 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 </code></pre> <p>a 64 bit variable is split in 2 32-bit locations.</p> <hr> <pre><code> 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 </code></pre> <p>a sum is performed with an <code>add</code> instruction on the lower 32 bits and then with an <code>adc</code> (add with carry) for the higher 32 bits. Subtraction is similar: the second operation is <code>sbb</code> (subtract with borrow).</p> <hr> <pre><code> 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 </code></pre> <p>The product and division are performed by calling special routines.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload