Greatest common divisor

You are encouraged to solve this task according to the task description, using any language you may know.
Task

Find the greatest common divisor   (GCD)   of two integers.


Greatest common divisor   is also known as   greatest common factor (gcf)   and   greatest common measure.



Related task

   least common multiple.


See also

   MathWorld entry:   greatest common divisor.
   Wikipedia entry:     greatest common divisor.


 
/* ARM assembly AARCH64 Raspberry PI 3B */
/*  program calPgcd64.s  */
 
/*******************************************/
/* Constantes file                         */
/*******************************************/
/* for this file see task include a file in language AArch64 assembly*/
.include "../includeConstantesARM64.inc"
 
/*********************************/
/* Initialized data              */
/*********************************/
.data
sMessResult:        .asciz "Number 1 : @ number 2 : @ PGCD  : @ \n"
szCarriageReturn:   .asciz "\n"
szMessError:        .asciz "Error PGCD !!\n"
 
/*********************************/
/* UnInitialized data            */
/*********************************/
.bss
sZoneConv:            .skip 24
/*********************************/
/*  code section                 */
/*********************************/
.text
.global main 
main:                               // entry of program 
 
    mov x20,36
    mov x21,18
    mov x0,x20
    mov x1,x21
    bl calPGCDmod
    bcs   99f                       // error ?
    mov x2,x0                       // pgcd
    mov x0,x20
    mov x1,x21
    bl displayResult
    mov x20,37
    mov x21,15
    mov x0,x20
    mov x1,x21
    bl calPGCDmod
    bcs   99f                       // error ?
    mov x2,x0                       // pgcd
    mov x0,x20
    mov x1,x21
    bl displayResult
 
 
    b 100f
99:                                 // display error
    ldr x0,qAdrszMessError
    bl affichageMess
100:                                // standard end of the program 
    mov x0, #0                      // return code
    mov x8, #EXIT                   // request to exit program
    svc #0                          // perform the system call
 
qAdrszCarriageReturn:     .quad szCarriageReturn
qAdrszMessError:          .quad szMessError
 
/***************************************************/
/*   Compute pgcd  modulo use */
/***************************************************/
/* x0 contains first number */
/* x1 contains second number */
/* x0 return  PGCD            */
/* if error carry set to 1    */
calPGCDmod:
    stp x1,lr,[sp,-16]!        // save  registres
    stp x2,x3,[sp,-16]!        // save  registres
    cbz x0,99f                 // if = 0 error
    cbz x1,99f
    cmp x0,0
    bgt 1f
    neg x0,x0                  // if negative inversion number 1
1:
    cmp x1,0
    bgt 2f
    neg x1,x1                  // if negative inversion number 2
2:
    cmp x0,x1                  // compare two numbers
    bgt 3f
    mov x2,x0                  // inversion
    mov x0,x1
    mov x1,x2
3:
    udiv x2,x0,x1              // division
    msub x0,x2,x1,x0           // compute remainder
    cmp x0,0
    bgt 2b                     // loop
    mov x0,x1
    cmn x0,0                   // clear carry
    b 100f
99:                            // error
    mov x0,0
    cmp x0,0                   // set carry
100:
    ldp x2,x3,[sp],16          // restaur des  2 registres
    ldp x1,lr,[sp],16          // restaur des  2 registres
    ret                        // retour adresse lr x30
 
/***************************************************/
/*   display result */
/***************************************************/
/* x0 contains first number */
/* x1 contains second number */
/* x2 contains  PGCD         */
displayResult:
    stp x1,lr,[sp,-16]!          // save  registres
    mov x3,x1                    // save x1
    ldr x1,qAdrsZoneConv
    bl conversion10              // décimal conversion 
    ldr x0,qAdrsMessResult
    ldr x1,qAdrsZoneConv         // insert conversion
    bl strInsertAtCharInc
    mov x4,x0                    // save message address
    mov x0,x3                    // conversion second number
    ldr x1,qAdrsZoneConv
    bl conversion10              // décimal conversion 
    mov x0,x4                    // move message address
    ldr x1,qAdrsZoneConv         // insert conversion
    bl strInsertAtCharInc
    mov x4,x0                    // save message address
    mov x0,x2                    // conversion pgcd
    ldr x1,qAdrsZoneConv
    bl conversion10              // décimal conversion 
    mov x0,x4                    // move message address
    ldr x1,qAdrsZoneConv         // insert conversion
    bl strInsertAtCharInc
    bl affichageMess             // display message
    ldp x1,lr,[sp],16            // restaur des  2 registres
    ret                          // retour adresse lr x30
qAdrsMessResult:          .quad sMessResult
qAdrsZoneConv:            .quad sZoneConv
/********************************************************/
/*        File Include fonctions                        */
/********************************************************/
/* for this file see task include a file in language AArch64 assembly */
.include "../includeARM64.inc"
 