2010-06-18 7 views

ответ

20

Компилятор будет синтезировать математические операции (или использовать вызовы функций), которые используют более одной команды ЦП для выполнения операции. Например, операция добавления добавит компоненты низкого порядка (низкие слова) значений long long и затем выполнит выполнение этой операции и подаст ее в операцию добавления в словах высокого порядка long long.

Так следующий код 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-битных значений задолго до появления long long.

1

Скорее всего как класс, а не изначально. таким же образом любой компилятор может/может поддерживать любой большой набор чисел.

9

Внутренне, тип представлен высоким словом и низким слова, как:

struct long 
{ 
    int32 highWord; 
    uint32_t lowWord; 
} 

компилятор должен знать, если это 32-разрядная или 64-разрядная среда, а затем выбирает правильный reprenstations из число - если оно 64 бит, это можно сделать изначально, если оно 32 бит, компилятор должен позаботиться о математике между верхним/нижним словом.

Если вы посмотрите в math.h, вы можете увидеть функции, используемые для этого, и использовать их самостоятельно. В дополнение, обратите внимание на разницу между little-endian и big-endian (see wiki), использование зависит от операционной системы.

+1

Две дополнительные вещи: во-первых, порядок этой структуры зависит от машинного порядка. – Joshua

+0

Во-вторых, функции, которые работают с этой структурой, доступны вам. Они объявлены в математике. – Joshua

+0

thirs 'lowByte' действительно будет' uint32_t' :-P –

2

Говоря о архитектуре 32-разрядной (или 64 или любой другой), обычно является лишь приближением того, на что способен процессор. Обычно вы ссылаетесь только на ширину указателей с этим числом, арифметика может быть совсем другой. Например, архитектура x86 имеет 32-битные указатели, большинство арифметических операций выполняется в 32-битных регистрах, но также имеет встроенную поддержку некоторых базовых 64-разрядных операций.

Также вы не должны следить за тем, чтобы стандартные стандартные типы имели определенную ширину. В частности, длинный длинный не менее 64 бит, но может быть шире. Используйте typedefs int32_t, int64_t, если вы хотите быть уверенно в отношении ширины.

Если вы хотите знать, что ССАГПЗ (или любой другой компилятор) делает с тех пор долго вы должны смотреть в спецификации для конкретной целевой платформы

2

Это достаточно легко просто компилировать и тестировать, если у вас есть доступная 32-битная система. gcc имеет флаг -S, который включает выход ассемблера. Вот что он производит на моем 32-битном Intel:

// 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 
// a-b 
subl %ecx, %eax 
sbbl %ebx, %edx 
// etc 
Смежные вопросы