1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71
| #include <stdio.h>
typedef struct {
unsigned H, L;
} type64;
typedef struct {
unsigned H, mH, mL, L;
} type128;
void mul128( type64 *op1, type64 *op2, type128 *result)
{
__asm
{
push esi // esi et edi doivent etre sauvés
push edi // les registres e?x peuvent etre librement modifiés
mov esi,op1 // esi et edi pointent sur les deux opérandes
mov edi,op2
mov eax,[esi]type64.L // poids faible du premier opérande
mov ebx,[edi]type64.L // poids faible du deuxième opérande
mul ebx // le poids faible (EAX) de la première multiplication...
push eax // ...est le poids faible du résultat final, on le stocke sur la pile
mov ecx,edx // sauve le poids fort de la première mult. dans ecx
mov eax,[esi]type64.H // poids fort premier opérande dans eax
mul ebx
add eax,ecx
adc edx,0
push eax // la première ligne de la mult. est complètement stockée dans la pile
push edx //
mov ebx,[edi]type64.H // poids fort du deuxième opérande
mov eax,[esi]type64.L // poids faible premier opérande
mul ebx
mov ecx,edx // sauve le poids fort dans ecx (comme précédemment)
mov edi,eax // on n'utilisera plus la dexième opérande jusqu'à la fin, on peut l'utiliser
mov eax,[esi]type64.H // poids fort premier opérande
mul ebx
add eax,ecx
adc edx,0
pop ebx // restaure la première ligne
pop ecx
add ecx,edi // effectue les sommes partielles
adc eax,ebx
adc edx,0
mov edi,result // edi pointe sur la struture résultat
pop [edi]type128.L // récupère le poids faible du résultat depuis la pile
mov [edi]type128.mL,ecx
mov [edi]type128.mH,eax
mov [edi]type128.H,edx
pop edi
pop esi
}
};
int main()
{
type64 a, b;
type128 r;
a.H=0xFFFFFFFF;
a.L=0xFFFFFFFF;
b.H=0xEEEEEEEE;
b.L=0xEEEEEEEE;
mul128(&a, &b, &r);
printf("%08X%08X * %08X%08X = %08X%08X%08X%08X\r\n", a.H, a.L, b.H, b.L, r.H, r.mH, r.mL, r.L);
return 0;
}; |
Partager