; Trouve et retourne le plus grand diviseur commun de deux entiers. ; Utilise l'algorithme d'Euclide : divise le plus grand entier par le ; plus petit; si le reste est égal à 0, le plus petit entier est le PGDC, ; sinon ce dernier devient le grand entier et le reste le plus petit ; l'opération est alors répétée. Evite la récursivité du code. ; ; Testé avec MASM et TASM. ; ; Appelable depuis C en near comme: ; unsigned int gcd(unsigned int int1, unsigned int int2); ; structure des paramètres: parms struc dw ? ;BP empilé dw ? ;adresse de retour empilée int1 dw ? ;entiers pour trouver int2 dw ? ;le PGDC parms ends .model small .code public gcd align 2 _gcd proc near push bp ;préserve la stack frame de l'appelant mov bp,sp ;configure notre stack frame push si ;préserve les variables registre de l'appelant push di ;Bascule si nécessaire pour que int1 >= int2 mov ax,int1[bp] mov bx,int2[bp] cmp ax,bx ;est-ce que int1 >= int2? Jnb IntsSet ;oui, xchg ax,bx ;non, basculons int1 et int2 IntsSet: ; Faisons un tour de boucle, en divisant int1 par int2 et en testant le reste, ; le reste jusqu'à ce que le reste soit égal à 0. A chaque tour, si le reste n'est pas ; égal à 0, ; nous allouons int2 à int1, et le reste à int2, puis nous répétons l'opération. GCDLoop: ;si le reste de int1 divisé par ;int2 est égal à 0, alors int2 est le PGDC sub dx,dx ;prépare int1 dans DX:AX pour la division div bx ;int1/int2; le reste est dans DX and dx,dx ;est-ce que le reste est égal à zéro? jz Done ;oui, alors int2 (BX) est le PGDC ;non, alors déplaçons int2 dans int1 et ;le reste dans int2, puis répétons ;l'opération mov ax,bx ;int1 = int2; mov bx,dx ;int2 = reste de DIV ;---Début du déroulement de la boucle; trois répétitions--- sub dx,dx ;prépare int1 dans DX:AX pour la r division div bx ;int1/int2; le reste est dans DX and dx,dx ;est-ce que le reste est égal à zéro? jz Done ;oui, alors int2 (BX) est le PGDC mov ax,bx ;int1 = int2; mov bx,dx ;int2 = reste de DIV ;--- sub dx,dx ;prépare int1 dans DX:AX pour la division div bx ;int1/int2; le reste est dans DX and dx,dx ;est-ce que le reste est égal à zéro? jz Done ;oui, alors int2 (BX) est le PGDC mov ax,bx ;int1 = int2; mov bx,dx ;int2 = reste de DIV ;--- sub dx,dx ;prépare int1 dans DX:AX pour la division div bx ;int1/int2; le reste est dans DX and dx,dx ;est-ce que le reste est égal à zéro? jz Done ;oui, alors int2 (BX) est le PGDC mov ax,bx ;int1 = int2; mov bx,dx ;int2 = reste de DIV ;---Fin du déroulement de la boucle--- jmp GCDLoop align 2 Done: mov ax,bx ;retourne le PGDC pop di ;restaure les variables registre de l'appelant pop si pop bp ;restaure la stack frame de l'appelant ret _gcd endp end