2010-06-18 16 views

Odpowiedz

20

Kompilator zsyntetyzuje operacje matematyczne (lub korzysta z wywołań funkcji), które używają więcej niż jednej instrukcji CPU, aby wykonać operację. Na przykład operacja dodawania doda komponenty niskiego rzędu (niskie słowa) wartości long long, a następnie podejmie operację dodawania i doda ją do operacji dodawania dla słów o wysokim priorytecie long long.

więc następujący kod C:

long long a; 
long long b; 
long long c; 

// ... 
c = a + b; 

może być reprezentowany przez sekwencję instrukcji, która wygląda mniej więcej tak:

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 

A jeśli wziąć pod uwagę przez chwilę, kompilatory dla 8 i 16 bitów systemy musiały robić tego typu rzeczy dla wartości 16 i/lub 32-bitowych na długo przed powstaniem long long.

1

Najprawdopodobniej jako klasa, nie w sposób natywny. w ten sam sposób jakikolwiek kompilator może/może obsługiwać dowolny zestaw dużych liczb.

9

Wewnętrznie typ reprezentowany jest przez wysokiej słowem i niskiej słowa, jak:

struct long 
{ 
    int32 highWord; 
    uint32_t lowWord; 
} 

Kompilator musi wiedzieć, czy jest to środowisko 32-bitowe lub 64-bitowe, a następnie dobiera odpowiednie reprenstations z liczba - jeśli jest 64-bitowa, może być wykonana natywnie, jeśli jest 32-bitowa, kompilator musi zająć się matematyką pomiędzy high/lowword.

Jeśli zajrzysz w mat.h, zobaczysz funkcje używane do tego i użyjesz ich sam. Z drugiej strony należy pamiętać o różnicy między little-endian i big-endian (see wiki), użycie zależy od systemu operacyjnego.

+1

Dwie dodatkowe rzeczy: po pierwsze, kolejność tej struktury zależy od zamówienia urządzenia. – Joshua

+0

Po drugie, wywołania funkcji, które działają na tej strukturze, są dostępne dla ciebie. Są one zadeklarowane w matematyce.h. – Joshua

+0

thirs "lowByte" będzie naprawdę "uint32_t' :-P –

2

Mówiąc, że architektura ma 32 bity (lub 64 lub cokolwiek innego) jest zwykle tylko przybliżeniem tego, do czego zdolny jest procesor. Zwykle odnosisz się tylko do szerokości wskaźników z tą liczbą, arytmetyka może być całkiem inna. Np. Architektura x86 ma wskaźniki 32-bitowe, większość arytmetyki jest wykonywana w rejestrach 32-bitowych, ale ma również natywną obsługę niektórych podstawowych operacji 64-bitowych.

Nie powinieneś również mieć wrażenia, że ​​standardowe typy liczb całkowitych mają określoną szerokość. W szczególności długi long jest co najmniej 64-bitowy, ale może być szerszy. Użyj typedefs int32_t, int64_t, jeśli chcesz mieć pewność co do szerokości.

Jeśli chcesz wiedzieć, jakie gcc (lub inny kompilator) robi z długo długo trzeba zajrzeć do specyfikacji dla danej platformy docelowej

2

to dość łatwe po prostu skompilować i przetestować, jeśli masz dostępny system 32-bitowy. gcc ma flagę -S, która włącza wyjście asemblerowe. Oto, co produkuje na moim 32-bitowym 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 
Powiązane problemy