{{works with|as|Raspberry Pi}}
<syntaxhighlight lang="arm assembly">

/* ARM assembly Raspberry PI  */
/*  program arith.s   */
/* Constantes    */
.equ STDOUT, 1
.equ WRITE,  4
.equ EXIT,   1

/***********************/
/* Initialized data */
/***********************/
.data
szMessError:      .asciz " Two numbers in command line please ! \n"       @ message
szRetourLigne: .asciz "\n"
szMessResult:  .asciz "Resultat "      @ message result
sMessValeur:   .fill 12, 1, ' '
                   .asciz "\n"
szMessAddition: .asciz "addition :"
szMessSoustraction: .asciz "soustraction :"
szMessMultiplication: .asciz "multiplication :"
szMessDivision: .asciz "division :"
szMessReste: .asciz "reste :"
   
/***********************/				   
/* No Initialized data */
/***********************/
.bss
iValeur:  .skip  4     @ reserve 4 bytes in memory

.text
.global main 
main:
    push {fp,lr}                @ save des  2 registres
    add fp,sp,#8                @ fp <- adresse début
    ldr r0,[fp]                 @ recup number of parameter in command line
    cmp r0,#3
    blt error
    ldr r0,[fp,#8]              @ adresse of 1er number
    bl conversionAtoD
    mov r3,r0
    ldr r0,[fp,#12]             @ adresse of 2eme number
    bl conversionAtoD
    mov r4,r0
    @ addition
    add r0,r3,r4
    ldr r1,iAdrsMessValeur      @ result in r0
    bl conversion10S            @ call function with 2 parameter (r0,r1)
    ldr r0,iAdrszMessResult
    bl affichageMess            @ display message
    ldr r0,iAdrszMessAddition
    bl affichageMess            @ display message
    ldr r0,iAdrsMessValeur
    bl affichageMess            @ display message
    @ soustraction
    sub r0,r3,r4
    ldr r1,=sMessValeur                 
    bl conversion10S            @ call function with 2 parameter (r0,r1)
    ldr r0,iAdrszMessResult
    bl affichageMess            @ display message
    ldr r0,iAdrszMessSoustraction
    bl affichageMess            @ display message
    ldr r0,iAdrsMessValeur
    bl affichageMess            @ display message

    @ multiplication
    mul r0,r3,r4
    ldr r1,=sMessValeur                 
    bl conversion10S            @ call function with 2 parameter (r0,r1)
    ldr r0,iAdrszMessResult
    bl affichageMess            @ display message
    ldr r0,iAdrszMessMultiplication
    bl affichageMess            @ display message
    ldr r0,iAdrsMessValeur
    bl affichageMess            @ display message
   
    @ division 
    mov r0,r3
    mov r1,r4
    bl division
    mov r0,r2                   @ quotient
    ldr r1,=sMessValeur                 
    bl conversion10S            @ call function with 2 parameter (r0,r1)
    ldr r0,iAdrszMessResult
    bl affichageMess            @ display message
    ldr r0,iAdrszMessDivision
    bl affichageMess            @ display message
    ldr r0,iAdrsMessValeur
    bl affichageMess            @ display message

    mov r0,r3                   @ remainder
    ldr r1,=sMessValeur                 
    bl conversion10S            @ call function with 2 parameter (r0,r1)
    ldr r0,iAdrszMessResult
    bl affichageMess            @ display message
    ldr r0,iAdrszMessReste
    bl affichageMess            @ display message
    ldr r0,iAdrsMessValeur
    bl affichageMess            @ display message
 
    mov r0, #0                  @ return code
    b 100f
error:
    ldr r0,iAdrszMessError
    bl affichageMess            @ call function with 1 parameter (r0)
    mov r0, #1                  @ return code
100: /* end of  program */
    mov r7, #EXIT               @ request to exit program
    swi 0                       @ perform the system call
iAdrsMessValeur: .int sMessValeur	
iAdrszMessResult: .int szMessResult
iAdrszMessError: .int szMessError
iAdrszMessAddition: .int szMessAddition
iAdrszMessSoustraction: .int szMessSoustraction
iAdrszMessMultiplication: .int szMessMultiplication
iAdrszMessDivision: .int szMessDivision
iAdrszMessReste: .int szMessReste
/******************************************************************/
/*     affichage des messages   avec calcul longueur              */ 
/******************************************************************/
/* r0 contient l adresse du message */
affichageMess:
    push {fp,lr}        /* save des  2 registres */ 
    push {r0,r1,r2,r7}  /* save des autres registres */
    mov r2,#0           /* compteur longueur */
1:                      /*calcul de la longueur */
    ldrb r1,[r0,r2]     /* recup octet position debut + indice */
    cmp r1,#0           /* si 0 c est fini */
    beq 1f
    add r2,r2,#1        /* sinon on ajoute 1 */
    b 1b
1:                      /* donc ici r2 contient la longueur du message */
    mov r1,r0           /* adresse du message en r1 */
    mov r0,#STDOUT      /* code pour écrire sur la sortie standard Linux */
    mov r7, #WRITE      /* code de l appel systeme 'write' */
    swi #0              /* appel systeme */
    pop {r0,r1,r2,r7}   /* restaur des autres registres */
    pop {fp,lr}         /* restaur des  2 registres */ 
    bx lr	        /* retour procedure */	
/***************************************************/
/*   conversion registre en décimal   signé  */
/***************************************************/
/* r0 contient le registre   */
/* r1 contient l adresse de la zone de conversion */
conversion10S:
    push {fp,lr}      /* save des  2 registres frame et retour */
    push {r0-r5}      /* save autres registres  */
    mov r2,r1         /* debut zone stockage */
    mov r5,#'+'       /* par defaut le signe est + */
    cmp r0,#0         /* nombre négatif ? */
    movlt r5,#'-'     /* oui le signe est - */
    mvnlt r0,r0       /* et inversion en valeur positive */
    addlt r0,#1
    mov r4,#10       /* longueur de la zone */
1:                   /* debut de boucle de conversion */
    bl divisionpar10 /* division  */
    add r1,#48       /* ajout de 48 au reste pour conversion ascii */	
    strb r1,[r2,r4]  /* stockage du byte en début de zone r5 + la position r4 */
    sub r4,r4,#1     /* position précedente */
    cmp r0,#0     
    bne 1b	     /* boucle si quotient different de zéro */
    strb r5,[r2,r4]  /* stockage du signe à la position courante */
    subs r4,r4,#1    /* position précedente */
    blt  100f        /* si r4 < 0  fin  */
                     /* sinon il faut completer le debut de la zone avec des blancs */
    mov r3,#' '      /* caractere espace */	
2:
    strb r3,[r2,r4]  /* stockage du byte  */
    subs r4,r4,#1    /* position précedente */
    bge 2b           /* boucle si r4 plus grand ou egal a zero */
100:                 /* fin standard de la fonction  */
    pop {r0-r5}      /*restaur des autres registres */
    pop {fp,lr}      /* restaur des  2 registres frame et retour  */
    bx lr   

/***************************************************/
/*   division par 10   signé                       */
/* Thanks to http://thinkingeek.com/arm-assembler-raspberry-pi/*  
/* and   http://www.hackersdelight.org/            */
/***************************************************/
/* r0 contient le dividende   */
/* r0 retourne le quotient */	
/* r1 retourne le reste  */
divisionpar10:	
  /* r0 contains the argument to be divided by 10 */
   push {r2-r4}   /* save autres registres  */
   mov r4,r0 
   ldr r3, .Ls_magic_number_10 /* r1 <- magic_number */
   smull r1, r2, r3, r0   /* r1 <- Lower32Bits(r1*r0). r2 <- Upper32Bits(r1*r0) */
   mov r2, r2, ASR #2     /* r2 <- r2 >> 2 */
   mov r1, r0, LSR #31    /* r1 <- r0 >> 31 */
   add r0, r2, r1         /* r0 <- r2 + r1 */
   add r2,r0,r0, lsl #2   /* r2 <- r0 * 5 */
   sub r1,r4,r2, lsl #1   /* r1 <- r4 - (r2 * 2)  = r4 - (r0 * 10) */
   pop {r2-r4}
   bx lr                  /* leave function */
   .align 4
.Ls_magic_number_10: .word 0x66666667
/******************************************************************/
/*     Conversion d une chaine en nombre stocké dans un registre  */ 
/******************************************************************/
/* r0 contient l adresse de la zone terminée par 0 ou 0A */
conversionAtoD:
    push {fp,lr}      /* save des  2 registres */ 
    push {r1-r7}      /* save des autres registres */
    mov r1,#0
    mov r2,#10        /* facteur */
    mov r3,#0         /* compteur */
    mov r4,r0         /* save de l adresse dans r4 */
    mov r6,#0         /* signe positif par defaut */
    mov r0,#0         /* initialisation à 0 */ 
1:                    /* boucle d élimination des blancs du debut */
    ldrb r5,[r4,r3]   /* chargement dans r5 de l octet situé au debut + la position */
    cmp r5,#0         /* fin de chaine -> fin routine */
    beq 100f
    cmp r5,#0x0A      /* fin de chaine -> fin routine */
    beq 100f
    cmp r5,#' '       /* blanc au début */
    bne 1f            /* non on continue */
    add r3,r3,#1      /* oui on boucle en avançant d un octet */
    b 1b
1:
    cmp r5,#'-'       /* premier caracteres est -    */
    moveq r6,#1       /* maj du registre r6 avec 1 */
    beq 3f            /* puis on avance à la position suivante */
2:                    /* debut de boucle de traitement des chiffres */
    cmp r5,#'0'       /* caractere n est pas un chiffre */
    blt 3f
    cmp r5,#'9'       /* caractere n est pas un chiffre */
    bgt 3f
                      /* caractère est un chiffre */
    sub r5,#48
    ldr r1,iMaxi      /*verifier le dépassement du registre  */  
    cmp r0,r1
    bgt 99f
    mul r0,r2,r0     /* multiplier par facteur */
    add r0,r5        /* ajout à r0 */
3:
    add r3,r3,#1     /* avance à la position suivante */
    ldrb r5,[r4,r3]  /* chargement de l octet */
    cmp r5,#0        /* fin de chaine -> fin routine */
    beq 4f
    cmp r5,#10       /* fin de chaine -> fin routine */
    beq 4f
    b 2b             /* boucler */ 
4:
    cmp r6,#1        /* test du registre r6 pour le signe */
    bne 100f
    mov r1,#-1
    mul r0,r1,r0    /* si negatif, on multiplie par -1 */
    b 100f
99:                 /* erreur de dépassement */
    ldr r1,=szMessErrDep
    bl   afficheerreur 
    mov r0,#0       /* en cas d erreur on retourne toujours zero */
100:
    pop {r1-r7}     /* restaur des autres registres */
    pop {fp,lr}     /* restaur des  2 registres */ 
    bx lr           /* retour procedure */	
/* constante programme */	
iMaxi: .int 1073741824	
szMessErrDep:  .asciz  "Nombre trop grand : dépassement de capacite de 32 bits. :\n"
.align 4
/*=============================================*/
/* division entiere non signée                */
/*============================================*/
division:
    /* r0 contains N */
    /* r1 contains D */
    /* r2 contains Q */
    /* r3 contains R */
    push {r4, lr}
    mov r2, #0              /* r2 ? 0 */
    mov r3, #0              /* r3 ? 0 */
    mov r4, #32             /* r4 ? 32 */
    b 2f
1:
    movs r0, r0, LSL #1    /* r0 ? r0 << 1 updating cpsr (sets C if 31st bit of r0 was 1) */
    adc r3, r3, r3         /* r3 ? r3 + r3 + C. This is equivalent to r3 ? (r3 << 1) + C */
 
    cmp r3, r1             /* compute r3 - r1 and update cpsr */
    subhs r3, r3, r1       /* if r3 >= r1 (C=1) then r3 ? r3 - r1 */
    adc r2, r2, r2         /* r2 ? r2 + r2 + C. This is equivalent to r2 ? (r2 << 1) + C */
2:
    subs r4, r4, #1        /* r4 ? r4 - 1 */
    bpl 1b                 /* if r4 >= 0 (N=0) then branch to .Lloop1 */
 
    pop {r4, lr}
    bx lr