__ int64 на 32-разрядной машине?

Взгляните на реализацию Apache Commons класса Tailer . Кажется, что он также обрабатывает вращение журнала.

25
задан koa 22 April 2010 в 15:48
поделиться

3 ответа

Почему вы находите это удивительным? Ничто не мешает компилятору поддерживать 64-, 128- или более-битные целочисленные типы на 32-битной машине. Компилятор может даже поддерживать 57- и 91-битные типы, если это так. На практике поддержка 2N-битной целочисленной арифметики на N-битной машине является относительно простой задачей, поскольку набор команд типичной машины часто разрабатывается с учетом такого рода функциональности.

6
ответ дан AnT 28 November 2019 в 21:03
поделиться

Это работает, потому что 64-битные целочисленные типы данных являются частью спецификации языка .

Компилятор для языка ДОЛЖЕН позволять вам работать с 64-разрядными целыми числами (и, конечно, получать правильные результаты).

Ваша программа должна работать (и работать точно так же), независимо от того, нацелены ли вы на 64-битную, 32-битную, 16-битную или 8-битную машину (что позволяет компилятор).

Кто бы ни написал компилятор, он должен был сделать все, что нужно , чтобы каждый поддерживаемый тип данных работал на на каждом целевом типе процессора.

Поддержка потенциально «более высоких» типов данных уже была решена , так что вам не придется делать это самостоятельно.

Как?

Очевидно, что принятие кода, который управляет 16-разрядными арифметическими операциями, и преобразование его в машинный код, работающий на 16-разрядном (или более высоком) процессоре, является «легкой» работой для компилятора, почти прямой перевод. Z = X + Y может переводиться как mov a,(X); add a,(Y); mov (Z),a;.

И наоборот, принять код, который управляет 64-разрядными арифметическими операциями, и преобразовать его в машинный код, который выполняется на 32-разрядном (или более низком) процессоре, является более сложным. Компилятору предстоит проделать больше работы, работая с 32-битными фрагментами каждого операнда за раз. Есть и другие способы сделать это.

Полученный машинный код может использовать несколько встроенных инструкций (больший код, более быстрое выполнение). Z = X + Y может переводиться как mov a,(X); adc a,(Y); mov (Z),a; mov a,CARRY; adc a,(X+1); adc a,(Y+1); mov (Z+1),a;.

Полученный машинный код может вызывать расширенные арифметические подпрограммы (меньший код, более медленное выполнение). Z = X + Y может переводиться как mov a,X; call GET64; mov a,Y; call ADD64; mov a,Z; call STORE64;.

0
ответ дан A876 28 November 2019 в 21:03
поделиться

Точно так же 32-битная арифметика работала в 16-битных системах.

В этом случае он использует 2 32-битных адреса памяти, чтобы вместе сформировать 64-битное число. Сложение / вычитание - это просто, вы делаете это по частям, единственная проблема - перенос переноса из нижней части в верхнюю. Для умножения / деления это сложнее (т.е. больше инструкций).

Это очевидно медленно, немного медленнее, чем 32-битная арифметика для умножения, но если вам это нужно, она есть для вас. А когда вы переходите на 64-битный процессор компилятор, он автоматически оптимизируется до одной инструкции с большим размером слова.

Реализация 64-битного умножения в Visual Studio 2010 Professional на 32-битном процессоре, скомпилированная в режиме выпуска, выглядит так:

_allmul PROC NEAR

A       EQU     [esp + 4]       ; stack address of a
B       EQU     [esp + 12]      ; stack address of b

        mov     eax,HIWORD(A)
        mov     ecx,HIWORD(B)
        or      ecx,eax         ;test for both hiwords zero.
        mov     ecx,LOWORD(B)
        jnz     short hard      ;both are zero, just mult ALO and BLO

        mov     eax,LOWORD(A)
        mul     ecx

        ret     16              ; callee restores the stack

hard:
        push    ebx

A2      EQU     [esp + 8]       ; stack address of a
B2      EQU     [esp + 16]      ; stack address of b

        mul     ecx             ;eax has AHI, ecx has BLO, so AHI * BLO
        mov     ebx,eax         ;save result

        mov     eax,LOWORD(A2)
        mul     dword ptr HIWORD(B2) ;ALO * BHI
        add     ebx,eax         ;ebx = ((ALO * BHI) + (AHI * BLO))

        mov     eax,LOWORD(A2)  ;ecx = BLO
        mul     ecx             ;so edx:eax = ALO*BLO
        add     edx,ebx         ;now edx has all the LO*HI stuff

        pop     ebx

        ret     16              ; callee restores the stack

Как видите, это НАМНОГО медленнее, чем обычное умножение.

36
ответ дан 28 November 2019 в 21:03
поделиться
Другие вопросы по тегам:

Похожие вопросы: