Works with: as version Raspberry Pi
/* ARM assembly Raspberry PI  */
/*  program incstring.s   */

/* Constantes    */
.equ BUFFERSIZE,   100
.equ STDIN,  0     @ Linux input console
.equ STDOUT, 1     @ Linux output console
.equ EXIT,   1     @ Linux syscall
.equ READ,   3     @ Linux syscall
.equ WRITE,  4     @ Linux syscall
/* Initialized data */
.data
szMessNum:           .asciz "Enter number : \n"
szCarriageReturn:  .asciz "\n"
szMessResult:       .ascii "Increment number is = "      @ message result
sMessValeur:        .fill 12, 1, ' '
                       .asciz "\n"

/* UnInitialized data */
.bss
sBuffer:    .skip    BUFFERSIZE

/*  code section */
.text
.global main
main:                /* entry of program  */
    push {fp,lr}    /* saves 2 registers */

    ldr r0,iAdrszMessNum
    bl affichageMess
    mov r0,#STDIN         @ Linux input console
    ldr r1,iAdrsBuffer   @ buffer address
    mov r2,#BUFFERSIZE   @ buffer size
    mov r7, #READ         @ request to read datas
    swi 0                  @ call system
    ldr r1,iAdrsBuffer    @ buffer address
    mov r2,#0                @ end of string
    strb r2,[r1,r0]         @ store byte at the end of input string (r0
    @
    ldr r0,iAdrsBuffer    @ buffer address
    bl conversionAtoD    @ conversion string in number in r0
    @ increment r0
    add r0,#1
    @ conversion register to string
    ldr r1,iAdrsMessValeur
    bl conversion10S       @ call conversion
    ldr r0,iAdrszMessResult
    bl affichageMess            @ display message

100:   /* standard end of the program */
    mov r0, #0                  @ return code
    pop {fp,lr}                 @restaur 2 registers
    mov r7, #EXIT              @ request to exit program
    swi 0                       @ perform the system call

iAdrsMessValeur:        .int sMessValeur
iAdrszMessNum:           .int szMessNum
iAdrsBuffer:             .int sBuffer
iAdrszMessResult:       .int szMessResult
iAdrszCarriageReturn:  .int szCarriageReturn
/******************************************************************/
/*     display text with size calculation                         */
/******************************************************************/
/* r0 contains the address of the message */
affichageMess:
    push {fp,lr}    			/* save  registres */
    push {r0,r1,r2,r7}    		/* save others registers */
    mov r2,#0   				/* counter length */
1:      /* loop length calculation */
    ldrb r1,[r0,r2]  			/* read octet start position + index */
    cmp r1,#0       			/* if 0 its over */
    addne r2,r2,#1   			/* else add 1 in the length */
    bne 1b          			/* and loop */
                                /* so here r2 contains the length of the message */
    mov r1,r0        			/* address message in r1 */
    mov r0,#STDOUT      		/* code to write to the standard output Linux */
    mov r7, #WRITE             /* code call system "write" */
    swi #0                      /* call systeme */
    pop {r0,r1,r2,r7}     		/* restaur others registers */
    pop {fp,lr}    				/* restaur des  2 registres */
    bx lr	        			/* return  */

 /******************************************************************/
/*     Convert a string to a number stored in a registry          */
/******************************************************************/
/* r0 contains the address of the area terminated by 0 or 0A */
/* r0 returns a number                           */
conversionAtoD:
    push {fp,lr}         @ save 2 registers
    push {r1-r7}         @ save others registers
    mov r1,#0
    mov r2,#10           @ factor
    mov r3,#0            @ counter
    mov r4,r0            @ save address string -> r4
    mov r6,#0            @ positive sign by default
    mov r0,#0            @ initialization to 0
1:     /* early space elimination loop */
    ldrb r5,[r4,r3]     @ loading in r5 of the byte located at the beginning + the position
    cmp r5,#0            @ end of string -> end routine
    beq 100f
    cmp r5,#0x0A        @ end of string -> end routine
    beq 100f
    cmp r5,#' '          @ space ?
    addeq r3,r3,#1      @ yes we loop by moving one byte
    beq 1b
    cmp r5,#'-'          @ first character is -
    moveq r6,#1         @  1 -> r6
    beq 3f              @ then move on to the next position
2:   /* beginning of digit processing loop */
    cmp r5,#'0'          @ character is not a number
    blt 3f
    cmp r5,#'9'          @ character is not a number
    bgt 3f
    /* character is a number */
    sub r5,#48
    umull r0,r1,r2,r0         @ multiply par factor 10
	cmp r1,#0           @ overflow ?
    bgt 99f            @ overflow error
    add r0,r5            @ add to  r0
3:
    add r3,r3,#1         @ advance to the next position
    ldrb r5,[r4,r3]     @ load byte
    cmp r5,#0            @ end of string -> end routine
    beq 4f
    cmp r5,#0x0A            @ end of string -> end routine
    beq 4f
    b 2b                 @ loop
4:
    cmp r6,#1            @ test r6 for sign
    moveq r1,#-1
    muleq r0,r1,r0       @ if negatif, multiply par -1
    b 100f
99:  /* overflow error */
    ldr r0,=szMessErrDep
    bl   affichageMess
    mov r0,#0      @ return  zero  if error
100:
    pop {r1-r7}          @ restaur other registers
    pop {fp,lr}          @ restaur   2 registers
    bx lr                 @return procedure
/* constante program */
szMessErrDep:  .asciz  "Too large: overflow 32 bits.\n"
.align 4

/***************************************************/
/*  Converting a register to a signed decimal      */
/***************************************************/
/* r0 contains value and r1 area address    */
conversion10S:
    push {r0-r4,lr}    @ save registers
    mov r2,r1       /* debut zone stockage */
    mov r3,#'+'     /* par defaut le signe est + */
    cmp r0,#0       @ negative number ?
    movlt r3,#'-'   @ yes
    mvnlt r0,r0     @ number inversion
    addlt r0,#1
    mov r4,#10       @ length area
1:  @ start loop
    bl divisionpar10
    add r1,#48   @ digit
    strb r1,[r2,r4]  @ store digit on area
    sub r4,r4,#1      @ previous position
    cmp r0,#0          @ stop if quotient = 0
    bne 1b

    strb r3,[r2,r4]  @ store signe
    subs r4,r4,#1    @ previous position
    blt  100f        @ if r4 < 0 -> end

    mov r1,#' '   @ space
2:
    strb r1,[r2,r4]  @store byte space
    subs r4,r4,#1    @ previous position
    bge 2b           @ loop if r4 > 0
100:
    pop {r0-r4,lr}   @ restaur registers
    bx lr

/***************************************************/
/*   division par 10   signé                       */
/* Thanks to http://thinkingeek.com/arm-assembler-raspberry-pi/*
/* and   http://www.hackersdelight.org/            */
/***************************************************/
/* r0 dividende   */
/* r0 quotient */
/* r1 remainder  */
divisionpar10:
    /* r0 contains the argument to be divided by 10 */
    push {r2-r4}   /* save registers  */
    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


Works with: as version Raspberry Pi
/* ARM assembly Raspberry PI  */
/*  program sattolo.s   */

/************************************/
/* Constantes                       */
/************************************/
.equ STDOUT, 1     @ Linux output console
.equ EXIT,   1     @ Linux syscall
.equ WRITE,  4     @ Linux syscall
/*********************************/
/* Initialized data              */
/*********************************/
.data
sMessResult:      .ascii "Value  : "
sMessValeur:       .fill 11, 1, ' '            @ size => 11
szCarriageReturn: .asciz "\n"

.align 4
iGraine:  .int 123456
.equ NBELEMENTS,      9
TableNumber:	     .int   4,6,7,10,11,15,22,30,35

/*********************************/
/* UnInitialized data            */
/*********************************/
.bss
/*********************************/
/*  code section                 */
/*********************************/
.text
.global main
main:                                           @ entry of program
    ldr r0,iAdrTableNumber                      @ address number table
    mov r1,#NBELEMENTS                          @ number of élements
    bl satShuffle
    ldr r2,iAdrTableNumber
    mov r3,#0
1:                                              @ loop display table
	ldr r0,[r2,r3,lsl #2]
    ldr r1,iAdrsMessValeur                      @ display value
    bl conversion10                             @ call function
    ldr r0,iAdrsMessResult
    bl affichageMess                            @ display message
    add r3,#1
    cmp r3,#NBELEMENTS - 1
    ble 1b

    ldr r0,iAdrszCarriageReturn
    bl affichageMess
    /*    2e shuffle             */
    ldr r0,iAdrTableNumber                     @ address number table
    mov r1,#NBELEMENTS                         @ number of élements
    bl satShuffle
    ldr r2,iAdrTableNumber
    mov r3,#0
2:                                             @ loop display table
    ldr r0,[r2,r3,lsl #2]
    ldr r1,iAdrsMessValeur                     @ display value
    bl conversion10                            @ call function
    ldr r0,iAdrsMessResult
    bl affichageMess                           @ display message
    add r3,#1
    cmp r3,#NBELEMENTS - 1
    ble 2b

100:                                           @ standard end of the program
    mov r0, #0                                 @ return code
    mov r7, #EXIT                              @ request to exit program
    svc #0                                     @ perform the system call

iAdrsMessValeur:          .int sMessValeur
iAdrszCarriageReturn:     .int szCarriageReturn
iAdrsMessResult:          .int sMessResult
iAdrTableNumber:          .int TableNumber

/******************************************************************/
/*     Sattolo Shuffle                                  */
/******************************************************************/
/* r0 contains the address of table */
/* r1 contains the number of elements */
satShuffle:
    push {r2-r6,lr}                                    @ save registers
    mov r5,r0                                          @ save table address
    mov r2,#1                                          @ start index
    mov r4,r1                                          @ last index + 1
1:
    sub r1,r2,#1                                       @ index - 1
    mov r0,r1                                          @ generate aleas
    bl genereraleas
    ldr r3,[r5,r1,lsl #2]                              @ swap number on the table
    ldr r6,[r5,r0,lsl #2]
    str r6,[r5,r1,lsl #2]
    str r3,[r5,r0,lsl #2]
    add r2,#1                                           @ next number
    cmp r2,r4                                           @ end ?
    ble 1b                                              @ no -> loop

100:
    pop {r2-r6,lr}
    bx lr                                               @ return

/******************************************************************/
/*     display text with size calculation                         */
/******************************************************************/
/* r0 contains the address of the message */
affichageMess:
    push {r0,r1,r2,r7,lr}                          @ save  registres
    mov r2,#0                                      @ counter length
1:                                                 @ loop length calculation
    ldrb r1,[r0,r2]                                @ read octet start position + index
    cmp r1,#0                                      @ if 0 its over
    addne r2,r2,#1                                 @ else add 1 in the length
    bne 1b                                         @ and loop
                                                   @ so here r2 contains the length of the message
    mov r1,r0                                      @ address message in r1
    mov r0,#STDOUT                                 @ code to write to the standard output Linux
    mov r7, #WRITE                                 @ code call system "write"
    svc #0                                         @ call systeme
    pop {r0,r1,r2,r7,lr}                           @ restaur des  2 registres */
    bx lr                                          @ return
/******************************************************************/
/*     Converting a register to a decimal unsigned                */
/******************************************************************/
/* r0 contains value and r1 address area   */
/* r0 return size of result (no zero final in area) */
/* area size => 11 bytes          */
.equ LGZONECAL,   10
conversion10:
    push {r1-r4,lr}                                 @ save registers
    mov r3,r1
    mov r2,#LGZONECAL

1:	                                            @ start loop
    bl divisionpar10U                               @unsigned  r0 <- dividende. quotient ->r0 reste -> r1
    add r1,#48                                      @ digit
    strb r1,[r3,r2]                                 @ store digit on area
    cmp r0,#0                                       @ stop if quotient = 0
    subne r2,#1                                     @ else previous position
    bne 1b	                                    @ and loop
                                                    @ and move digit from left of area
    mov r4,#0
2:
    ldrb r1,[r3,r2]
    strb r1,[r3,r4]
    add r2,#1
    add r4,#1
    cmp r2,#LGZONECAL
    ble 2b
                                                    @ and move spaces in end on area
    mov r0,r4                                       @ result length
    mov r1,#' '                                     @ space
3:
    strb r1,[r3,r4]                                 @ store space in area
    add r4,#1                                       @ next position
    cmp r4,#LGZONECAL
    ble 3b                                          @ loop if r4 <= area size

100:
    pop {r1-r4,lr}                                  @ restaur registres
    bx lr                                           @return

/***************************************************/
/*   division par 10   unsigned                    */
/***************************************************/
/* r0 dividende   */
/* r0 quotient */
/* r1 remainder  */
divisionpar10U:
    push {r2,r3,r4, lr}
    mov r4,r0                                       @ save value
    //mov r3,#0xCCCD                                @ r3 <- magic_number lower  raspberry 3
    //movt r3,#0xCCCC                               @ r3 <- magic_number higter raspberry 3
    ldr r3,iMagicNumber                             @ r3 <- magic_number    raspberry 1 2
    umull r1, r2, r3, r0                            @ r1<- Lower32Bits(r1*r0) r2<- Upper32Bits(r1*r0)
    mov r0, r2, LSR #3                              @ r2 <- r2 >> shift 3
    add r2,r0,r0, lsl #2                            @ r2 <- r0 * 5
    sub r1,r4,r2, lsl #1                            @ r1 <- r4 - (r2 * 2)  = r4 - (r0 * 10)
    pop {r2,r3,r4,lr}
    bx lr                                           @ leave function
iMagicNumber:  	.int 0xCCCCCCCD
/***************************************************/
/*   Generation random number                  */
/***************************************************/
/* r0 contains limit  */
genereraleas:
    push {r1-r4,lr}                                  @ save registers
    ldr r4,iAdriGraine
    ldr r2,[r4]
    ldr r3,iNbDep1
    mul r2,r3,r2
    ldr r3,iNbDep1
    add r2,r2,r3
    str r2,[r4]                                      @ maj de la graine pour l appel suivant
    cmp r0,#0
    beq 100f
    mov r1,r0                                        @ divisor
    mov r0,r2                                        @ dividende
    bl division
    mov r0,r3                                        @ résult = remainder

100:                                                 @ end function
    pop {r1-r4,lr}                                   @ restaur registers
    bx lr                                            @ return
/*****************************************************/
iAdriGraine: .int iGraine
iNbDep1: .int 0x343FD
iNbDep2: .int 0x269EC3
/***************************************************/
/* integer division unsigned                       */
/***************************************************/
division:
    /* r0 contains dividend */
    /* r1 contains divisor */
    /* r2 returns quotient */
    /* r3 returns remainder */
    push {r4, lr}
    mov r2, #0                                         @ init quotient
    mov r3, #0                                         @ init remainder
    mov r4, #32                                        @ init counter bits
    b 2f
1:                                                     @ loop
    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 loop
    pop {r4, lr}
    bx lr

implement the Sattolo cycle algorithm which shuffles an array ensuring each element ends up in a new position. The algorithm works by iterating from the last index to the first, selecting a random index within the range, and swapping the elements at these two indices. The algorithm modifies the input array in-place, but can be adjusted to return a new array or iterate from left to right if necessary. The key distinction from the Knuth shuffle is the range from which the random index is selected.


Works with: as version Raspberry Pi  or android 32 bits with application Termux
/* ARM assembly Raspberry PI  */
/*  program averageMed.s   */
/* use quickselect look pseudo code in wikipedia  quickselect */

/************************************/
/* Constantes                       */
/************************************/
/* for constantes see task include a file in arm assembly */
.include "../constantes.inc"

/*********************************/
/* Initialized data              */
/*********************************/
.data
szMessResultValue:        .asciz "Result  : "
szCarriageReturn:         .asciz "\n"

.align 4
TableNumber:              .float 4.1, 5.6, 7.2, 1.7, 9.3, 4.4, 3.2
.equ NBELEMENTS,      (. - TableNumber) / 4
TableNumber2:	          .float 4.1, 7.2, 1.7, 9.3, 4.4, 3.2
.equ NBELEMENTS2,      (. - TableNumber2) / 4
/*********************************/
/* UnInitialized data            */
/*********************************/
.bss
sZoneConv:             .skip 24
sZoneConv1:            .skip 24
/*********************************/
/*  code section                 */
/*********************************/
.text
.global main
main:                                    @ entry of program

    ldr r0,iAdrTableNumber               @ address number table
    mov r1,#0                            @ index first item
    mov r2,#NBELEMENTS -1                @ index last item
    bl searchMedian
    ldr r0,iAdrTableNumber2               @ address number table 2
    mov r1,#0                             @ index first item
    mov r2,#NBELEMENTS2 -1                @ index last item
    bl searchMedian

100:                                     @ standard end of the program
    mov r0, #0                           @ return code
    mov r7, #EXIT                        @ request to exit program
    svc #0                               @ perform the system call

iAdrszCarriageReturn:     .int szCarriageReturn
iAdrTableNumber:          .int TableNumber
iAdrTableNumber2:         .int TableNumber2
iAdrsZoneConv:            .int sZoneConv
iAdrszMessResultValue:    .int szMessResultValue
/***************************************************/
/*   search median term in float array                       */
/***************************************************/
/* r0 contains the address of table */
/* r1 contains index of first item  */
/* r2 contains index of last item   */
searchMedian:
    push {r1-r5,lr}                @ save registers
    mov r5,r0                      @ save array address
    add r4,r1,r2
    add r4,r4,#1                   @ sum numbers terms
    tst r4,#1                      @ odd ?
    bne 1f
    lsr r3,r4,#1                   @ compute median index
    bl select                      @ call selection
    vmov s0,r0                     @ save first result
    sub r3,r3,#1                   @ second term
    mov r0,r5
    bl select                      @ call selection
    vmov s1,r0                     @ save 2ieme résult
    vadd.f32 s0,s1                 @ compute average two résults
    mov r0,#2
    vmov s1,r0
    vcvt.f32.u32 s1,s1             @ conversion integer -> float
    vdiv.f32 s0,s0,s1
    b 2f
1:                                 @ even
    lsr r3,r4,#1
    bl select                      @ call selection
    vmov s0,r0
2:
    ldr r0,iAdrsZoneConv           @ conversion float in decimal string
    bl convertirFloat
    mov r0,#3                      @ and display result
    ldr r1,iAdrszMessResultValue
    ldr r2,iAdrsZoneConv
    ldr r3,iAdrszCarriageReturn
    bl displayStrings
100:                               @ end function
    pop {r1-r5,pc}                 @ restaur  register
/***************************************************/
/*   Appel récursif selection                      */
/***************************************************/
/* r0 contains the address of table */
/* r1 contains index of first item  */
/* r2 contains index of last item   */
/* r3 contains search index */
/* r0 return final value in float */
/* remark : the final result is a float returned in r0 register */
select:
    push {r1-r6,lr}                @ save registers
    mov r6,r3                      @ save search index
    cmp r1,r2                      @ first = last ?
    ldreq r0,[r0,r1,lsl #2]        @ return value of first index
    beq 100f                       @ yes -> end
    add r3,r1,r2
    lsr r3,r3,#1                   @ compute median pivot
    mov r4,r0                      @ save r0
    mov r5,r2                      @ save r2
    bl partition                   @ cutting into 2 parts
    cmp r6,r0                      @ pivot is ok ?
    ldreq r0,[r4,r0,lsl #2]        @ return value
    beq 100f
    bgt 1f
    sub r2,r0,#1                   @ index partition  - 1
    mov r0,r4                      @ array address
    mov r3,r6                      @ search index
    bl select                      @ select lower part
    b 100f
1:
    add r1,r0,#1                   @ index begin = index partition + 1
    mov r0,r4                      @ array address
    mov r2,r5                      @ last item
    mov r3,r6                      @ search index
    bl select                      @ select higter part
 100:                              @ end function
    pop {r1-r6,pc}                 @ restaur  register
/******************************************************************/
/*      Partition table elements                                */
/******************************************************************/
/* r0 contains the address of table */
/* r1 contains index of first item  */
/* r2 contains index of last item   */
/* r3 contains index of pivot */
partition:
    push {r1-r6,lr}                                    @ save registers
    ldr r4,[r0,r3,lsl #2]                              @ load value of pivot
    ldr r5,[r0,r2,lsl #2]                              @ load value last index
    str r5,[r0,r3,lsl #2]                              @ swap value of pivot
    str r4,[r0,r2,lsl #2]                              @ and value last index
    mov r3,r1                                          @ init with first index
1:                                                     @ begin loop
    ldr r6,[r0,r3,lsl #2]                              @ load value
    cmp r6,r4                                          @ compare loop value and pivot value
    ldrlt r5,[r0,r1,lsl #2]                            @ if < swap value table
    strlt r6,[r0,r1,lsl #2]
    strlt r5,[r0,r3,lsl #2]
    addlt r1,#1                                        @ and increment index 1
    add r3,#1                                          @ increment index 2
    cmp r3,r2                                          @ end ?
    blt 1b                                             @ no loop
    ldr r5,[r0,r1,lsl #2]                              @ swap value
    str r4,[r0,r1,lsl #2]
    str r5,[r0,r2,lsl #2]
    mov r0,r1                                          @ return index partition
100:
    pop {r1-r6,pc}

/***************************************************/
/*   display multi strings                    */
/***************************************************/
/* r0  contains number strings address */
/* r1 address string1 */
/* r2 address string2 */
/* r3 address string3 */
/* other address on the stack */
/* thinck to add  number other address * 4 to add to the stack */
displayStrings:            @ INFO:  displayStrings
    push {r1-r4,fp,lr}     @ save des registres
    add fp,sp,#24          @ save paraméters address (6 registers saved * 4 bytes)
    mov r4,r0              @ save strings number
    cmp r4,#0              @ 0 string -> end
    ble 100f
    mov r0,r1              @ string 1
    bl affichageMess
    cmp r4,#1              @ number > 1
    ble 100f
    mov r0,r2
    bl affichageMess
    cmp r4,#2
    ble 100f
    mov r0,r3
    bl affichageMess
    cmp r4,#3
    ble 100f
    mov r3,#3
    sub r2,r4,#4
1:                         @ loop extract address string on stack
    ldr r0,[fp,r2,lsl #2]
    bl affichageMess
    subs r2,#1
    bge 1b
100:
    pop {r1-r4,fp,pc}
/******************************************************************/
/*     Conversion Float                                            */
/******************************************************************/
/* s0  contains Float */
/* r0 contains address conversion area  mini 20 charactèrs*/
/* r0 return result length */
/* see https://blog.benoitblanchon.fr/lightweight-float-to-string/ */
convertirFloat:
    push {r1-r7,lr}
    vpush {s0-s2}
    mov r6,r0                 @ save area address
    vmov r0,s0
    mov r1,#0
    vmov s1,r1
    movs r7,#0                @ result length
    movs r3,#'+'
    strb r3,[r6]              @ sign + forcing
    mov r2,r0
    lsls r2,#1                @ extraction bit 31
    bcc 1f                    @ positive ?
    lsrs r0,r2,#1             @ raz sign if negative
    movs r3,#'-'              @ sign -
    strb r3,[r6]
1:
    adds r7,#1                @ next position
    cmp r0,#0                 @ case of positive or negative 0
    bne 2f
    movs r3,#'0'
    strb r3,[r6,r7]           @ store character 0
    adds r7,#1                @ next position
    movs r3,#0
    strb r3,[r6,r7]           @ store  0 final
    mov r0,r7                 @ return length
    b 100f                    @ and end
2:
    ldr r2,iMaskExposant
    mov r1,r0
    ands r1,r2                @ exposant = 255 ?
    cmp r1,r2
    bne 4f
    lsls r0,#10               @ bit 22 à 0 ?
    bcc 3f                    @ yes
    movs r2,#'N'              @ case of Nan. store byte, if not possible store int
    strb r2,[r6]              @ area no aligned
    movs r2,#'a'
    strb r2,[r6,#1]
    movs r2,#'n'
    strb r2,[r6,#2]
    movs r2,#0                @ 0 final
    strb r2,[r6,#3]
    movs r0,#3                @ return length 3
    b 100f
3:                            @ case infini positive or négative
    movs r2,#'I'
    strb r2,[r6,r7]
    adds r7,#1
    movs r2,#'n'
    strb r2,[r6,r7]
    adds r7,#1
    movs r2,#'f'
    strb r2,[r6,r7]
    adds r7,#1
    movs r2,#0
    strb r2,[r6,r7]
    mov r0,r7
    b 100f
4:
    bl normaliserFloat
    mov r5,r0                @ save exposant
    VCVT.U32.f32  s2,s0      @ integer value of  integer part
    vmov r0,s2               @ integer part
    VCVT.F32.U32  s1,s2      @ conversion float
    vsub.f32 s1,s0,s1        @ extraction fract part
    vldr s2,iConst1
    vmul.f32 s1,s2,s1        @ to crop it in full

    VCVT.U32.f32  s1,s1      @ integer conversion
    vmov r4,s1               @ fract value
                             @ integer conversion in  r0
    mov r2,r6                @ save address area begin
    adds r6,r7
    mov r1,r6
    bl conversion10
    add r6,r0
    movs r3,#','
    strb r3,[r6]
    adds r6,#1

    mov r0,r4                @ conversion fractional part
    mov r1,r6
    bl conversion10SP        @ spécial routine with conservation begin 0
    add r6,r0
    subs r6,#1
                             @ remove trailing zeros
5:
    ldrb r0,[r6]
    cmp r0,#'0'
    bne 6f
    subs r6,#1
    b 5b
6:
    cmp r0,#','
    bne 7f
    subs r6,#1
7:
    adds r6,#1
    movs r3,#'E'
    strb r3,[r6]
    adds r6,#1
    mov r0,r5                  @ conversion exposant
    mov r3,r0
    lsls r3,#1
    bcc 4f
    rsbs r0,r0,#0
    movs r3,#'-'
    strb r3,[r6]
    adds r6,#1
4:
    mov r1,r6
    bl conversion10
    add r6,r0

    movs r3,#0
    strb r3,[r6]
    adds r6,#1
    mov r0,r6
    subs r0,r2                 @ return length result
    subs r0,#1                 @ - 0 final

100:
    vpop {s0-s2}
    pop {r1-r7,pc}
iMaskExposant:            .int 0xFF<<23
iConst1:                  .float 0f1E9

/***************************************************/
/*   normaliser float                              */
/***************************************************/
/* r0 contain float value (always positive value and <> Nan) */
/* s0 return new value  */
/* r0 return exposant */
normaliserFloat:
    push {lr}               @ save  registre
    vmov s0,r0              @ value float
    movs r0,#0              @ exposant
    vldr s1,iConstE7        @ no normalisation for value < 1E7
    vcmp.f32 s0,s1
    vmrs APSR_nzcv,FPSCR
    blo 10f                 @ if s0  < iConstE7

    vldr s1,iConstE32
    vcmp.f32 s0,s1
    vmrs APSR_nzcv,FPSCR
    blo 1f
    vldr s1,iConstE32
    vdiv.f32 s0,s0,s1
    adds r0,#32
1:
    vldr s1,iConstE16
    vcmp.f32 s0,s1
    vmrs APSR_nzcv,FPSCR
    blo 2f
    vldr s1,iConstE16
    vdiv.f32 s0,s0,s1
    adds r0,#16
2:
    vldr s1,iConstE8
    vcmp.f32 s0,s1
    vmrs APSR_nzcv,FPSCR
    blo 3f
    vldr s1,iConstE8
    vdiv.f32 s0,s0,s1
    adds r0,#8
3:
    vldr s1,iConstE4
    vcmp.f32 s0,s1
    vmrs APSR_nzcv,FPSCR
    blo 4f
    vldr s1,iConstE4
    vdiv.f32 s0,s0,s1
    adds r0,#4
4:
    vldr s1,iConstE2
    vcmp.f32 s0,s1
    vmrs APSR_nzcv,FPSCR
    blo 5f
    vldr s1,iConstE2
    vdiv.f32 s0,s0,s1
    adds r0,#2
5:
    vldr s1,iConstE1
    vcmp.f32 s0,s1
    vmrs APSR_nzcv,FPSCR
    blo 10f
    vldr s1,iConstE1
    vdiv.f32 s0,s0,s1
    adds r0,#1

10:
    vldr s1,iConstME5        @ pas de normalisation pour les valeurs > 1E-5
    vcmp.f32 s0,s1
    vmrs APSR_nzcv,FPSCR
    bhi 100f
    vldr s1,iConstME31
    vcmp.f32 s0,s1
    vmrs APSR_nzcv,FPSCR
    bhi 11f
    vldr s1,iConstE32

    vmul.f32 s0,s0,s1
    subs r0,#32
11:
    vldr s1,iConstME15
    vcmp.f32 s0,s1
    vmrs APSR_nzcv,FPSCR
    bhi 12f
    vldr s1,iConstE16
    vmul.f32 s0,s0,s1
    subs r0,#16
12:
    vldr s1,iConstME7
    vcmp.f32 s0,s1
    vmrs APSR_nzcv,FPSCR
    bhi 13f
    vldr s1,iConstE8
    vmul.f32 s0,s0,s1
    subs r0,#8
13:
    vldr s1,iConstME3
    vcmp.f32 s0,s1
    vmrs APSR_nzcv,FPSCR
    bhi 14f
    vldr s1,iConstE4
    vmul.f32 s0,s0,s1
    subs r0,#4
14:
    vldr s1,iConstME1
    vcmp.f32 s0,s1
    vmrs APSR_nzcv,FPSCR
    bhi 15f
    vldr s1,iConstE2
    vmul.f32 s0,s0,s1
    subs r0,#2
15:
    vldr s1,iConstE0
    vcmp.f32 s0,s1
    vmrs APSR_nzcv,FPSCR
    bhi 100f
    vldr s1,iConstE1
    vmul.f32 s0,s0,s1
    subs r0,#1

100:                       @ fin standard de la fonction
    pop {pc}               @ restaur des registres
.align 2
iConstE7:             .float 0f1E7
iConstE32:            .float 0f1E32
iConstE16:            .float 0f1E16
iConstE8:             .float 0f1E8
iConstE4:             .float 0f1E4
iConstE2:             .float 0f1E2
iConstE1:             .float 0f1E1
iConstME5:            .float 0f1E-5
iConstME31:           .float 0f1E-31
iConstME15:           .float 0f1E-15
iConstME7:            .float 0f1E-7
iConstME3:            .float 0f1E-3
iConstME1:            .float 0f1E-1
iConstE0:             .float 0f1E0
/******************************************************************/
/*     Décimal Conversion                                         */
/******************************************************************/
/* r0 contain value et r1 address conversion area   */
conversion10SP:
    push {r1-r6,lr}            @ save  registers
    mov r5,r1
    mov r4,#8
    mov r2,r0
    mov r1,#10                 @ conversion decimale
1:                             @ begin loop
    mov r0,r2                  @ copy number or quotients
    bl division                @ r0 dividende r1 divisor r2 quotient r3 remainder
    add r3,#48                 @ compute digit
    strb r3,[r5,r4]            @ store byte area address (r5) + offset (r4)
    subs r4,r4,#1              @ position précedente
    bge 1b                     @ and loop if not < zero
    mov r0,#8
    mov r3,#0
    strb r3,[r5,r0]            @ store 0 final
100:
    pop {r1-r6,pc}             @ restaur registers
/***************************************************/
/*      ROUTINES INCLUDE                           */
/***************************************************/
/* for this file see task include a file in language ARM assembly */
.include "../affichage.inc"

The code calculates the median value of a vector of floating-point numbers. It handles even number of elements by returning the average of the two middle values. The median is found using the selection algorithm for optimal time complexity. The code also includes tasks for calculating various statistical measures like mean, mode, and standard deviation. It also calculates moving (sliding window and cumulative) averages and different types of means such as arithmetic, geometric, harmonic, quadratic, and circular.


/ * linux GAS */

.global _start

.data

Fizz: .ascii "Fizz\n"
Buzz: .ascii "Buzz\n"
FizzAndBuzz: .ascii "FizzBuzz\n"

numstr_buffer: .skip 3
newLine: .ascii "\n"

.text

_start:

  bl FizzBuzz

  mov r7, #1
  mov r0, #0
  svc #0

FizzBuzz:

  push {lr}
  mov r9, #100

  fizzbuzz_loop:

    mov r0, r9
    mov r1, #15
    bl divide
    cmp r1, #0
    ldreq r1, =FizzAndBuzz
    moveq r2, #9
    beq fizzbuzz_print

    mov r0, r9
    mov r1, #3
    bl divide
    cmp r1, #0
    ldreq r1, =Fizz
    moveq r2, #5
    beq fizzbuzz_print

    mov r0, r9
    mov r1, #5
    bl divide
    cmp r1, #0
    ldreq r1, =Buzz
    moveq r2, #5
    beq fizzbuzz_print

    mov r0, r9
    bl make_num
    mov r2, r1
    mov r1, r0

    fizzbuzz_print:

      mov r0, #1
      mov r7, #4
      svc #0

      sub r9, #1
      cmp r9, #0

    bgt fizzbuzz_loop

  pop {lr}
  mov pc, lr

make_num:

  push {lr}
  ldr r4, =numstr_buffer
  mov r5, #4
  mov r6, #1

  mov r1, #100
  bl divide

  cmp r0, #0
  subeq r5, #1
  movne r6, #0

  add r0, #48
  strb r0, [r4, #0]

  mov r0, r1
  mov r1, #10
  bl divide

  cmp r0, #0
  movne r6, #0
  cmp r6, #1
  subeq r5, #1

  add r0, #48
  strb r0, [r4, #1]

  add r1, #48
  strb r1, [r4, #2]

  mov r2, #4
  sub r0, r2, r5
  add r0, r4, r0
  mov r1, r5

  pop {lr}
  mov pc, lr

divide:
  udiv r2, r0, r1
  mul r3, r1, r2
  sub r1, r0, r3
  mov r0, r2
  mov pc, lr

print numbers from 1 to 100, replacing multiples of three with 'Fizz', multiples of five with 'Buzz', and multiples of both three and five with 'FizzBuzz'.


Works with: as version Raspberry Pi  or android 32 bits with application Termux
/* ARM assembly Raspberry PI  */
/*  program sumandproduct.s   */

 /* REMARK 1 : this program use routines in a include file
   see task Include a file language arm assembly
   for the routine affichageMess conversion10
   see at end of this program the instruction include */
/* for constantes see task include a file in arm assembly */
/************************************/
/* Constantes                       */
/************************************/
.include "../constantes.inc"

/*********************************/
/* Initialized data              */
/*********************************/
.data
szMessSum:            .asciz "Sum = "
szMessProd:           .asciz "Product = "
szMessStart:          .asciz "Program 32 bits start.\n"
szCarriageReturn:     .asciz "\n"
szMessErreur:         .asciz "Overflow ! \n"

tabArray:       .int  2, 11, 19, 90, 55,1000
.equ TABARRAYSIZE,    (. - tabArray) / 4
/*********************************/
/* UnInitialized data            */
/*********************************/
.bss
sZoneConv:             .skip 24
/*********************************/
/*  code section                 */
/*********************************/
.text
.global main
main:                            @ entry of program
    ldr r0,iAdrszMessStart
    bl affichageMess
    ldr r2,iAdrtabArray
    mov r1,#0                    @ indice
    mov r0,#0                    @ sum init
1:
    ldr r3,[r2,r1,lsl #2]
    adds r0,r0,r3
    bcs 99f
    add r1,r1,#1
    cmp r1,#TABARRAYSIZE
    blt 1b

    ldr r1,iAdrsZoneConv
    bl conversion10              @ decimal conversion
    mov r3,#0
    strb r3,[r1,r0]
    mov r0,#3                   @ number string to display
    ldr r1,iAdrszMessSum
    ldr r2,iAdrsZoneConv         @ insert conversion in message
    ldr r3,iAdrszCarriageReturn
    bl displayStrings            @ display message

    ldr r2,iAdrtabArray
    mov r1,#0                    @ indice
    mov r0,#1                    @ product init
2:
    ldr r3,[r2,r1,lsl #2]
    umull r0,r4,r3,r0
    cmp r4,#0
    bne 99f
    add r1,r1,#1
    cmp r1,#TABARRAYSIZE
    blt 2b

    ldr r1,iAdrsZoneConv
    bl conversion10              @ decimal conversion
    mov r3,#0
    strb r3,[r1,r0]
    mov r0,#3                   @ number string to display
    ldr r1,iAdrszMessProd
    ldr r2,iAdrsZoneConv         @ insert conversion in message
    ldr r3,iAdrszCarriageReturn
    bl displayStrings            @ display message
    b 100f
99:
    ldr r0,iAdrszMessErreur
    bl affichageMess
100:                              @ standard end of the program
    mov r0, #0                    @ return code
    mov r7, #EXIT                 @ request to exit program
    svc #0                        @ perform the system call
iAdrszCarriageReturn:        .int szCarriageReturn
iAdrsZoneConv:               .int sZoneConv
iAdrszMessSum:               .int szMessSum
iAdrszMessProd:              .int szMessProd
iAdrszMessErreur:            .int szMessErreur
iAdrszMessStart:             .int szMessStart
iAdrtabArray:                .int tabArray

/***************************************************/
/*   display multi strings                    */
/***************************************************/
/* r0  contains number strings address */
/* r1 address string1 */
/* r2 address string2 */
/* r3 address string3 */
/* other address on the stack */
/* thinck to add  number other address * 4 to add to the stack */
displayStrings:            @ INFO:  displayStrings
    push {r1-r4,fp,lr}     @ save des registres
    add fp,sp,#24          @ save paraméters address (6 registers saved * 4 bytes)
    mov r4,r0              @ save strings number
    cmp r4,#0              @ 0 string -> end
    ble 100f
    mov r0,r1              @ string 1
    bl affichageMess
    cmp r4,#1              @ number > 1
    ble 100f
    mov r0,r2
    bl affichageMess
    cmp r4,#2
    ble 100f
    mov r0,r3
    bl affichageMess
    cmp r4,#3
    ble 100f
    mov r3,#3
    sub r2,r4,#4
1:                         @ loop extract address string on stack
    ldr r0,[fp,r2,lsl #2]
    bl affichageMess
    subs r2,#1
    bge 1b
100:
    pop {r1-r4,fp,pc}

/***************************************************/
/*      ROUTINES INCLUDE                           */
/***************************************************/
.include "../affichage.inc"

Calculate the sum and product of all integers in an array.


Works with: as version Raspberry Pi
/* ARM assembly Raspberry PI  */
/*  program copystr.s   */

/* Constantes    */
.equ STDOUT, 1     @ Linux output console
.equ EXIT,   1     @ Linux syscall
.equ WRITE,  4     @ Linux syscall
/* Initialized data */
.data
szString: .asciz "ABCDEFGHIJKLMNOPQRSTUVWXYZ\n"

/* UnInitialized data */
.bss
.align 4
iPtString:   .skip 4
szString1:    .skip 80

/*  code section */
.text
.global main
main:                /* entry of program  */
    push {fp,lr}    /* saves 2 registers */

    @ display start string
    ldr r0,iAdrszString
    bl affichageMess
    @ copy pointer string
    ldr r0,iAdrszString
    ldr r1,iAdriPtString
    str r0,[r1]
    @ control
    ldr r1,iAdriPtString
    ldr r0,[r1]
    bl affichageMess
    @ copy string
    ldr r0,iAdrszString
    ldr r1,iAdrszString1
1:
    ldrb r2,[r0],#1   @ read one byte and increment pointer one byte
    strb r2,[r1],#1   @ store one byte and increment pointer one byte
    cmp r2,#0          @ end of string ?
    bne 1b            @ no -> loop
    @ control
    ldr r0,iAdrszString1
    bl affichageMess

100:   /* standard end of the program */
    mov r0, #0                  @ return code
    pop {fp,lr}                 @restaur 2 registers
    mov r7, #EXIT              @ request to exit program
    swi 0                       @ perform the system call
iAdrszString:		.int szString
iAdriPtString:		.int iPtString
iAdrszString1:		.int szString1

/******************************************************************/
/*     display text with size calculation                         */
/******************************************************************/
/* r0 contains the address of the message */
affichageMess:
    push {fp,lr}    			/* save  registres */
    push {r0,r1,r2,r7}    		/* save others registers */
    mov r2,#0   				/* counter length */
1:      	/* loop length calculation */
    ldrb r1,[r0,r2]  			/* read octet start position + index */
    cmp r1,#0       			/* if 0 its over */
    addne r2,r2,#1   			/* else add 1 in the length */
    bne 1b          			/* and loop */
                                /* so here r2 contains the length of the message */
    mov r1,r0        			/* address message in r1 */
    mov r0,#STDOUT      		/* code to write to the standard output Linux */
    mov r7, #WRITE             /* code call system "write" */
    swi #0                      /* call systeme */
    pop {r0,r1,r2,r7}     		/* restaur others registers */
    pop {fp,lr}    				/* restaur des  2 registres */
    bx lr	        			/* return  */

"Implements functionality to copy a string's content and create an additional reference to an existing string where applicable."


.text
.global _start
	@@@	Implementation of F(n), n in R0. n is considered unsigned.
F:	tst	r0,r0		@ n = 0?
	moveq	r0,#1		@ In that case, the result is 1
	bxeq	lr		@ And we can return to the caller
	push	{r0,lr}		@ Save link register and argument to stack
	sub	r0,r0,#1	@ r0 -= 1    = n-1
	bl	F		@ r0 = F(r0) = F(n-1)
	bl	M		@ r0 = M(r0) = M(F(n-1))
	pop	{r1,lr}		@ Restore link register and argument in r1
	sub	r0,r1,r0	@ Result is n-F(M(n-1))
	bx	lr		@ Return to caller.

	@@@	Implementation of M(n), n in R0. n is considered unsigned.
M:	tst	r0,r0		@ n = 0?
	bxeq	lr		@ In that case the result is also 0; return.
	push	{r0,lr}		@ Save link register and argument to stack
	sub	r0,r0,#1	@ r0 -= 1    = n-1
	bl	M		@ r0 = M(r0) = M(n-1)
	bl	F		@ r0 = M(r0) = F(M(n-1))
	pop	{r1,lr}		@ Restore link register and argument in r1
	sub	r0,r1,r0	@ Result is n-M(F(n-1))
	bx	lr		@ Return to caller

	@@@	Print F(0..15) and M(0..15)
_start:	ldr	r1,=fmsg	@ Print values for F
	ldr	r4,=F
	bl	prfn
	ldr	r1,=mmsg	@ Print values for M
	ldr	r4,=M
	bl	prfn
	mov	r7,#1		@ Exit process
	swi	#0

	@@@	Helper function for output: print [r1], then [r4](0..15)
	@@@	This assumes [r4] preserves r3 and r4; M and F do.
prfn:	push	{lr}		@ Keep link register
	bl	pstr		@ Print the string
	mov	r3,#0		@ Start at 0
1:	mov	r0,r3		@ Call the function in r4 with current number
	blx	r4
	add	r0,r0,#'0	@ Make ASCII digit
	ldr	r1,=dgt		@ Store in digit string
	strb	r0,[r1]
	ldr	r1,=dstr	@ Print result
	bl	pstr
	add	r3,r3,#1	@ Next number
	cmp	r3,#15		@ Keep going up to and including 15
	bls	1b
	ldr	r1,=nl		@ Print newline afterwards
	bl	pstr
	pop	{pc}		@ Return to address on stack
	@@@	Print length-prefixed string r1 to stdout
pstr:	push	{lr}		@ Keep link register
	mov	r0,#1		@ stdout = 1
	ldrb	r2,[r1],#1	@ r2 = length prefix
	mov	r7,#4		@ 4 = write syscall
	swi	#0
	pop	{pc}		@ Return to address on stack
.data
fmsg:	.ascii	"\3F: "
mmsg:	.ascii	"\3M: "
dstr:	.ascii	"\2"
dgt:	.ascii	"* "
nl:	.ascii 	"\1\n"

implement two mutually recursive functions to compute the Hofstadter Female and Male sequences. The functions follow the defined rules: F(0) = 1, M(0) = 0, F(n) = n - M(F(n-1)) for n > 0, and M(n) = n - F(M(n-1)) for n > 0. The code also includes handling for ARM instruction set, which lacks specialized call and ret instructions. The program counter and stack pointer are managed manually, with r13 used as the system stack pointer and r14 storing the return address for a function. The code also includes implementation of push and pop instructions, and branch-and-link instructions for calling subroutines.


Works with: as version Raspberry Pi
/* ARM assembly Raspberry PI  */
/*  program binsearch.s   */

/************************************/
/* Constantes                       */
/************************************/
.equ STDOUT, 1     @ Linux output console
.equ EXIT,   1     @ Linux syscall
.equ WRITE,  4     @ Linux syscall
/*********************************/
/* Initialized data              */
/*********************************/
.data
sMessResult:        .ascii "Value find at index : "
sMessValeur:        .fill 11, 1, ' '            @ size => 11
szCarriageReturn:   .asciz "\n"
sMessRecursif:      .asciz "Recursive search : \n"
sMessNotFound:      .asciz "Value not found. \n"

.equ NBELEMENTS,      9
TableNumber:	     .int   4,6,7,10,11,15,22,30,35

/*********************************/
/* UnInitialized data            */
/*********************************/
.bss
/*********************************/
/*  code section                 */
/*********************************/
.text
.global main
main:                                           @ entry of program
    mov r0,#4                                   @ search first value
    ldr r1,iAdrTableNumber                      @ address number table
    mov r2,#NBELEMENTS                          @ number of élements
    bl bSearch
    ldr r1,iAdrsMessValeur                      @ display value
    bl conversion10                             @ call function
    ldr r0,iAdrsMessResult
    bl affichageMess                            @ display message

    mov r0,#11                                  @ search median value
    ldr r1,iAdrTableNumber
    mov r2,#NBELEMENTS
    bl bSearch
    ldr r1,iAdrsMessValeur                      @ display value
    bl conversion10                             @ call function
    ldr r0,iAdrsMessResult
    bl affichageMess                            @ display message

    mov r0,#12                                  @value not found
    ldr r1,iAdrTableNumber
    mov r2,#NBELEMENTS
    bl bSearch
    cmp r0,#-1
    bne 2f
    ldr r0,iAdrsMessNotFound
    bl affichageMess
    b 3f
2:
    ldr r1,iAdrsMessValeur                      @ display value
    bl conversion10                             @ call function
    ldr r0,iAdrsMessResult
    bl affichageMess                            @ display message
3:
    mov r0,#35                                  @ search last value
    ldr r1,iAdrTableNumber
    mov r2,#NBELEMENTS
    bl bSearch
    ldr r1,iAdrsMessValeur                      @ display value
    bl conversion10                             @ call function
    ldr r0,iAdrsMessResult
    bl affichageMess                            @ display message
/****************************************/
/*       recursive                      */
/****************************************/
    ldr r0,iAdrsMessRecursif
    bl affichageMess                            @ display message

    mov r0,#4                                   @ search first value
    ldr r1,iAdrTableNumber
    mov r2,#0                                   @ low index of elements
    mov r3,#NBELEMENTS - 1                      @ high index of elements
    bl bSearchR
    ldr r1,iAdrsMessValeur                      @ display value
    bl conversion10                             @ call function
    ldr r0,iAdrsMessResult
    bl affichageMess                            @ display message

    mov r0,#11
    ldr r1,iAdrTableNumber
    mov r2,#0
    mov r3,#NBELEMENTS - 1
    bl bSearchR
    ldr r1,iAdrsMessValeur                      @ display value
    bl conversion10                             @ call function
    ldr r0,iAdrsMessResult
    bl affichageMess                            @ display message

    mov r0,#12
    ldr r1,iAdrTableNumber
    mov r2,#0
    mov r3,#NBELEMENTS - 1
    bl bSearchR
    cmp r0,#-1
    bne 2f
    ldr r0,iAdrsMessNotFound
    bl affichageMess
    b 3f
2:
    ldr r1,iAdrsMessValeur                      @ display value
    bl conversion10                             @ call function
    ldr r0,iAdrsMessResult
    bl affichageMess                            @ display message
3:
    mov r0,#35
    ldr r1,iAdrTableNumber
    mov r2,#0
    mov r3,#NBELEMENTS - 1
    bl bSearchR
    ldr r1,iAdrsMessValeur                      @ display value
    bl conversion10                             @ call function
    ldr r0,iAdrsMessResult
    bl affichageMess                            @ display message

100:                                            @ standard end of the program
    mov r0, #0                                  @ return code
    mov r7, #EXIT                               @ request to exit program
    svc #0                                      @ perform the system call

iAdrsMessValeur:          .int sMessValeur
iAdrszCarriageReturn:     .int szCarriageReturn
iAdrsMessResult:          .int sMessResult
iAdrsMessRecursif:        .int sMessRecursif
iAdrsMessNotFound:        .int sMessNotFound
iAdrTableNumber:          .int TableNumber

/******************************************************************/
/*     binary search   iterative                                  */
/******************************************************************/
/* r0 contains the value to search */
/* r1 contains the adress of table */
/* r2 contains the number of elements */
/* r0 return index or -1 if not find */
bSearch:
    push {r2-r5,lr}                                 @ save registers
    mov r3,#0                                       @ low index
    sub r4,r2,#1                                    @ high index = number of elements - 1
1:
    cmp r3,r4
    movgt r0,#-1                                    @not found
    bgt 100f
    add r2,r3,r4                                    @ compute (low + high) /2
    lsr r2,#1
    ldr r5,[r1,r2,lsl #2]                           @ load value of table at index r2
    cmp r5,r0
    moveq r0,r2                                     @ find !!!
    beq 100f
    addlt r3,r2,#1                                  @ lower -> index low = index + 1
    subgt r4,r2,#1                                  @ bigger -> index high = index - 1
    b 1b                                            @ and loop
100:
    pop {r2-r5,lr}
    bx lr                       @ return
/******************************************************************/
/*     binary search   recursif                                  */
/******************************************************************/
/* r0 contains the value to search */
/* r1 contains the adress of table */
/* r2 contains the low index of elements */
/* r3 contains the high index of elements */
/* r0 return index or -1 if not find */
bSearchR:
    push {r2-r5,lr}                                  @ save registers
    cmp r3,r2                                        @ index high < low ?
    movlt r0,#-1                                     @ yes -> not found
    blt 100f

    add r4,r2,r3                                     @ compute (low + high) /2
    lsr r4,#1
    ldr r5,[r1,r4,lsl #2]                            @ load value of table at index r4
    cmp r5,r0
    moveq r0,r4                                      @ find !!!
    beq 100f

    bgt 1f                                           @ bigger ?
    add r2,r4,#1                                     @ no new search with low = index + 1
    bl bSearchR
    b 100f
1:                                                   @ bigger
    sub r3,r4,#1                                     @ new search with high = index - 1
    bl bSearchR
100:
    pop {r2-r5,lr}
    bx lr                                            @ return
/******************************************************************/
/*     display text with size calculation                         */
/******************************************************************/
/* r0 contains the address of the message */
affichageMess:
    push {r0,r1,r2,r7,lr}                          @ save  registres
    mov r2,#0                                      @ counter length
1:                                                 @ loop length calculation
    ldrb r1,[r0,r2]                                @ read octet start position + index
    cmp r1,#0                                      @ if 0 its over
    addne r2,r2,#1                                 @ else add 1 in the length
    bne 1b                                         @ and loop
                                                   @ so here r2 contains the length of the message
    mov r1,r0                                      @ address message in r1
    mov r0,#STDOUT                                 @ code to write to the standard output Linux
    mov r7, #WRITE                                 @ code call system "write"
    svc #0                                         @ call systeme
    pop {r0,r1,r2,r7,lr}                           @ restaur des  2 registres
    bx lr                                          @ return
/******************************************************************/
/*     Converting a register to a decimal unsigned                */
/******************************************************************/
/* r0 contains value and r1 address area   */
/* r0 return size of result (no zero final in area) */
/* area size => 11 bytes          */
.equ LGZONECAL,   10
conversion10:
    push {r1-r4,lr}                                 @ save registers
    mov r3,r1
    mov r2,#LGZONECAL

1:	                                            @ start loop
    bl divisionpar10U                               @unsigned  r0 <- dividende. quotient ->r0 reste -> r1
    add r1,#48                                      @ digit
    strb r1,[r3,r2]                                 @ store digit on area
    cmp r0,#0                                       @ stop if quotient = 0
    subne r2,#1                                     @ else previous position
    bne 1b	                                    @ and loop
                                                    @ and move digit from left of area
    mov r4,#0
2:
    ldrb r1,[r3,r2]
    strb r1,[r3,r4]
    add r2,#1
    add r4,#1
    cmp r2,#LGZONECAL
    ble 2b
                                                     @ and move spaces in end on area
    mov r0,r4                                        @ result length
    mov r1,#' '                                      @ space
3:
    strb r1,[r3,r4]                                  @ store space in area
    add r4,#1                                        @ next position
    cmp r4,#LGZONECAL
    ble 3b                                           @ loop if r4 <= area size

100:
    pop {r1-r4,lr}                                   @ restaur registres
    bx lr                                            @return

/***************************************************/
/*   division par 10   unsigned                    */
/***************************************************/
/* r0 dividende   */
/* r0 quotient */
/* r1 remainder  */
divisionpar10U:
    push {r2,r3,r4, lr}
    mov r4,r0                                        @ save value
    //mov r3,#0xCCCD                                 @ r3 <- magic_number lower  raspberry 3
    //movt r3,#0xCCCC                                @ r3 <- magic_number higter raspberry 3
    ldr r3,iMagicNumber                              @ r3 <- magic_number    raspberry 1 2
    umull r1, r2, r3, r0                             @ r1<- Lower32Bits(r1*r0) r2<- Upper32Bits(r1*r0)
    mov r0, r2, LSR #3                               @ r2 <- r2 >> shift 3
    add r2,r0,r0, lsl #2                             @ r2 <- r0 * 5
    sub r1,r4,r2, lsl #1                             @ r1 <- r4 - (r2 * 2)  = r4 - (r0 * 10)
    pop {r2,r3,r4,lr}
    bx lr                                            @ leave function
iMagicNumber:  	.int 0xCCCCCCCD

The code implements a binary search algorithm, which divides a range of values into halves to find an unknown value. It takes a sorted integer array, a starting point, an ending point, and a "secret value" as inputs. The algorithm can be either recursive or iterative and returns whether the number was in the array and its index if found. The code also includes variations of the binary search algorithm that return the leftmost or rightmost insertion point for the given value. It also handles potential overflow bugs.


Works with: as version Raspberry Pi
/* ARM assembly Raspberry PI  */
/*  program commandLine.s   */

/* Constantes    */
.equ STDOUT, 1                         @ Linux output console
.equ EXIT,   1                         @ Linux syscall
.equ WRITE,  4                         @ Linux syscall
/* Initialized data */
.data
szCarriageReturn:  .asciz "\n"

/* UnInitialized data */
.bss
.align 4

/*  code section */
.text
.global main
main:                                   @ entry of program
    push {fp,lr}                        @ saves registers
    add fp,sp,#8                        @  fp <- start address
    ldr r4,[fp]                         @ number of Command line arguments
    add r5,fp,#4                        @ first parameter address
    mov r2,#0                           @ init loop counter
loop:
    ldr r0,[r5,r2,lsl #2]               @ string address parameter
    bl affichageMess                    @ display string
    ldr r0,iAdrszCarriageReturn
    bl affichageMess                    @ display carriage return
    add r2,#1                           @ increment counter
    cmp r2,r4                           @ number parameters ?
    blt loop                            @ loop

100:                                    @ standard end of the program
    mov r0, #0                          @ return code
    pop {fp,lr}                         @restaur  registers
    mov r7, #EXIT                       @ request to exit program
    swi 0                               @ perform the system call

iAdrszCarriageReturn:    .int szCarriageReturn

/******************************************************************/
/*     display text with size calculation                         */
/******************************************************************/
/* r0 contains the address of the message */
affichageMess:
    push {r0,r1,r2,r7,lr}                          @ save  registres
    mov r2,#0                                      @ counter length
1:                                                 @ loop length calculation
    ldrb r1,[r0,r2]                                @ read octet start position + index
    cmp r1,#0                                      @ if 0 its over
    addne r2,r2,#1                                 @ else add 1 in the length
    bne 1b                                         @ and loop
                                                   @ so here r2 contains the length of the message
    mov r1,r0                                      @ address message in r1
    mov r0,#STDOUT                                 @ code to write to the standard output Linux
    mov r7, #WRITE                                 @ code call system "write"
    svc #0                                         @ call systeme
    pop {r0,r1,r2,r7,lr}                           @ restaur 2 registres
    bx lr                                          @ return

The code retrieves and prints the list of command-line arguments provided to the program, such as 'myprogram -c "alpha beta" -h "gamma"'. It also includes functionalities for intelligent parsing of these arguments.


Works with: as version Raspberry Pi
/* ARM assembly Raspberry PI  */
/*  program nroot.s   */
/* compile with option -mfpu=vfpv3 -mfloat-abi=hard */
/* link with gcc. Use C function for display float */

/* Constantes               */
.equ EXIT,   1                         @ Linux syscall

/* Initialized data */
.data
szFormat1:         .asciz " %+09.15f\n"
.align 4
iNumberA:          .int 1024

/* UnInitialized data */
.bss
.align 4

/*  code section */
.text
.global main
main:                                   @ entry of program
    push {fp,lr}                        @ saves registers

    /* root 10ieme de 1024  */
    ldr r0,iAdriNumberA                 @ number address
    ldr r0,[r0]
    vmov s0,r0                          @
    vcvt.f64.s32 d0, s0                 @conversion in float single précision (32 bits)
    mov r0,#10                          @ N
    bl nthRoot
    ldr r0,iAdrszFormat1                @ format
    vmov r2,r3,d0
    bl printf                           @ call C function !!!
                                        @ Attention register dn lost !!!
    /* square root of 2   */
    vmov.f64 d1,#2.0                    @ conversion 2 in float register d1
    mov r0,#2                           @ N
    bl nthRoot
    ldr r0,iAdrszFormat1                @ format
    vmov r2,r3,d0
    bl printf                           @ call C function !!!

100:                                    @ standard end of the program
    mov r0, #0                          @ return code
    pop {fp,lr}                         @restaur  registers
    mov r7, #EXIT                       @ request to exit program
    swi 0                               @ perform the system call

iAdrszFormat1:           .int szFormat1
iAdriNumberA:            .int iNumberA

/******************************************************************/
/*     compute  nth root                                          */
/******************************************************************/
/* r0 contains N   */
/* d0 contains the value                 */
/* d0 return result                      */
nthRoot:
    push {r1,r2,lr}                    @ save  registers
    vpush {d1-d8}                         @ save float registers
    FMRX    r1,FPSCR                   @ copy FPSCR into r1
    BIC     r1,r1,#0x00370000          @ clears STRIDE and LEN
    FMXR    FPSCR,r1                   @ copy r1 back into FPSCR

    vmov s2,r0                         @
    vcvt.f64.s32 d6, s2                @ N conversion in float double précision (64 bits)
    sub r1,r0,#1                       @ N - 1
    vmov s8,r1                         @
    vcvt.f64.s32 d4, s8                @conversion in float double précision (64 bits)
    vmov.f64 d2,d0                     @ a = A
    vdiv.F64 d3,d0,d6                  @ b = A/n
    adr r2,dfPrec                      @ load précision
    vldr d8,[r2]
1:                                     @ begin loop
    vmov.f64 d2,d3                     @ a <- b
    vmul.f64 d5,d3,d4                  @ (N-1)*b

    vmov.f64 d1,#1.0                   @ constante 1 -> float
    mov r2,#0                          @ loop indice
2:                                     @ compute pow (n-1)
    vmul.f64 d1,d1,d3                  @
    add r2,#1
    cmp r2,r1                          @ n -1 ?
    blt 2b                             @ no -> loop
    vdiv.f64 d7,d0,d1                  @ A / b pow (n-1)
    vadd.f64 d7,d7,d5                  @ + (N-1)*b
    vdiv.f64 d3,d7,d6                  @ / N -> new b
    vsub.f64 d1,d3,d2                  @ compute gap
    vabs.f64 d1,d1                     @ absolute value
    vcmp.f64 d1,d8                     @ compare float maj FPSCR
    fmstat                             @ transfert FPSCR -> APSR
                                       @ or use VMRS APSR_nzcv, FPSCR
    bgt 1b                             @ if gap > précision -> loop
    vmov.f64 d0,d3                     @ end return result in d0

100:
    vpop {d1-d8}                       @ restaur float registers
    pop {r1,r2,lr}                     @ restaur arm registers
    bx lr
dfPrec:            .double 0f1E-10     @ précision

Implement the principal nth root algorithm for a positive real number A.


Works with: as version Raspberry Pi
/* ARM assembly Raspberry PI  */
/*  program game24.s   */

/* REMARK 1 : this program use routines in a include file
   see task Include a file language arm assembly
   for the routine affichageMess conversion10
   see at end of this program the instruction include */
/* for constantes see task include a file in arm assembly */
/************************************/
/* Constantes                       */
/************************************/
.include "../constantes.inc"
.equ STDIN,      0       @ Linux input console
.equ READ,       3       @ Linux syscall
.equ NBDIGITS,   4       @ digits number
.equ TOTAL,      24
.equ BUFFERSIZE, 100
.equ STACKSIZE,  10      @ operator and digits number items in stacks

/*********************************/
/* Initialized data              */
/*********************************/
.data
szMessRules:         .ascii "24 Game\n"
                    .ascii "The program will display four randomly-generated \n"
                    .ascii "single-digit numbers and will then prompt you to enter\n"
                    .ascii "an arithmetic expression followed by <enter> to sum \n"
                    .ascii "the given numbers to 24.\n"
                    .asciz "Exemple : 9+8+3+4   or (7+5)+(3*4) \n\n"

szMessExpr:         .asciz "Enter your expression (or type (q)uit to exit or (n) for other digits): \n"
//szMessErrChoise:    .asciz "invalid choice.\n "
szMessDigits:       .asciz "The four digits are @ @ @ @ and the score is 24. \n"
szMessNoDigit:      .asciz "Error : One digit is not in digits list !! \n"
szMessSameDigit:    .asciz "Error : Two digits are same !! \n"
szMessOK:           .asciz "It is OK. \n"
szMessNotOK:        .asciz "Error, it is not ok  total = @ \n"
szMessErrOper:      .asciz "Unknow Operator (+,-,$,/,(,)) \n"
szMessNoparen:      .asciz "no opening parenthesis !! \n"
szMessErrParen:     .asciz "Error parenthesis number !! \n"
szMessNoalldigits:  .asciz "One or more digits not used !!\n"
szMessNewGame:      .asciz "New game (y/n) ? \n"
szCarriageReturn:   .asciz "\n"
.align 4
iGraine:  .int 123456
/*********************************/
/* UnInitialized data            */
/*********************************/
.bss
sZoneConv:        .skip 24
sBuffer:          .skip BUFFERSIZE
iTabDigit:        .skip 4 * NBDIGITS
iTabTopDigit:     .skip 4 * NBDIGITS
/*********************************/
/*  code section                 */
/*********************************/
.text
.global main
main:                                 @ entry of program

    ldr r0,iAdrszMessRules            @ display rules
    bl affichageMess
1:
    mov r3,#0
    ldr r12,iAdriTabDigit
    ldr r11,iAdriTabTopDigit
    ldr r5,iAdrszMessDigits
2:                                    @ loop generate random digits
    mov r0,#8
    bl genereraleas
    add r0,r0,#1
    str r0,[r12,r3,lsl #2]            @ store in table
    mov r1,#0
    str r1,[r11,r3,lsl #2]            @ raz top table
    ldr r1,iAdrsZoneConv
    bl conversion10                   @ call decimal conversion
    mov r2,#0
    strb r2,[r1,r0]                   @ reduce size display area with zéro final
    mov r0,r5
    ldr r1,iAdrsZoneConv              @ insert conversion in message
    bl strInsertAtCharInc
    mov r5,r0
    add r3,r3,#1
    cmp r3,#NBDIGITS                  @ end ?
    blt 2b                            @ no -> loop
    mov r0,r5
    bl affichageMess
3:                                    @ loop human entry
    ldr r0,iAdrszMessExpr
    bl affichageMess
    bl saisie                         @ entry
    cmp r0,#'q'
    beq 100f
    cmp r0,#'Q'
    beq 100f
    cmp r0,#'n'
    beq 1b
    cmp r0,#'N'
    beq 1b

    bl evalExpr                      @ expression evaluation
    cmp r0,#0                        @ ok ?
    bne 3b                           @ no - > loop

10:                                  @ display new game ?
    ldr r0,iAdrszCarriageReturn
    bl affichageMess
    ldr r0,iAdrszMessNewGame
    bl affichageMess
    bl saisie
    cmp r0,#'y'
    beq 1b
    cmp r0,#'Y'
    beq 1b

100:                                  @ standard end of the program
    mov r0, #0                        @ return code
    mov r7, #EXIT                     @ request to exit program
    svc #0                            @ perform the system call

iAdrszCarriageReturn:     .int szCarriageReturn
iAdrszMessRules:          .int szMessRules
iAdrszMessDigits:         .int szMessDigits
iAdrszMessExpr:           .int szMessExpr
iAdrszMessNewGame:        .int szMessNewGame
iAdrsZoneConv:            .int sZoneConv
iAdriTabDigit:            .int iTabDigit
iAdriTabTopDigit:         .int iTabTopDigit
/******************************************************************/
/*            evaluation expression                                       */
/******************************************************************/
/* r0 return 0 if ok -1 else */
evalExpr:
    push {r1-r11,lr}           @ save registers

    mov r0,#0
    ldr r1,iAdriTabTopDigit
    mov r2,#0
1:                             @ loop init table top digits
    str r0,[r1,r2,lsl #2]
    add r2,r2,#1
    cmp r2,#NBDIGITS
    blt 1b

    sub sp,sp,#STACKSIZE * 4   @ stack operator
    mov fp,sp
    sub sp,sp,#STACKSIZE * 4   @ stack digit
    mov r1,sp
    ldr r10,iAdrsBuffer
    mov r8,#0                  @ indice character in buffer
    mov r7,#0                  @ indice digits stack
    mov r2,#0                  @ indice operator stack
1:                             @ begin loop
    ldrb r9,[r10,r8]
    cmp r9,#0xA               @ end expression ?
    beq 90f
    cmp r9,#' '               @ space  ?
    addeq r8,r8,#1             @ loop
    beq 1b
    cmp r9,#'('               @ left parenthesis -> store in operator stack
    streq r9,[fp,r2,lsl #2]
    addeq r2,r2,#1
    addeq r8,r8,#1             @ and loop
    beq 1b
    cmp r9,#')'               @ right parenthesis ?
    bne 3f
    mov r0,fp                  @ compute operator stack until left parenthesis
    sub r2,r2,#1
2:
    ldr r6,[fp,r2,lsl #2]
    cmp r6,#'('                @ left parenthesis
    addeq r8,r8,#1             @ end ?
    beq 1b                     @ and loop
    sub r7,r7,#1               @ last digit
    mov r3,r7
    bl compute
    sub r2,r2,#1
    cmp r2,#0
    bge 2b
    ldr r0,iAdrszMessNoparen   @ no left parenthesis in stack
    bl affichageMess
    mov r0,#-1
    b 100f
3:
    cmp r9,#'+'               @ addition
    beq 4f
    cmp r9,#'-'               @ soustraction
    beq 4f
    cmp r9,#'*'               @ multiplication
    beq 4f
    cmp r9,#'/'               @ division
    beq 4f

    b 5f                       @ not operator

4:                             @ control priority and depile stacks
    mov r0,fp
    mov r3,r7
    mov r4,r9
    bl depileOper
    mov r7,r3
    add r8,r8,#1
    b 1b                       @ and loop

5:                             @  digit
    sub r9,r9,#0x30
    mov r0,r9
    bl digitControl
    cmp r0,#0                  @ error ?
    bne 100f
    str r9,[r1,r7,lsl #2]     @ store digit in digits stack
    add r7,r7,#1

    add r8,r8,#1
    beq 1b

    b 100f
90:                            @ compute all stack operators
    mov r0,fp
    sub r7,r7,#1
91:
    subs r2,r2,#1
    blt 92f
    mov r3,r7
    bl compute
    sub r7,r7,#1
    b 91b
92:
    ldr r0,[r1]                 @ total = first value on digits stack
    cmp r0,#TOTAL               @ control total
    beq 93f                     @ ok
    ldr r1,iAdrsZoneConv
    bl conversion10             @ call decimal conversion
    mov r2,#0
    strb r2,[r1,r0]
    ldr r0,iAdrszMessNotOK
    ldr r1,iAdrsZoneConv        @ insert conversion in message
    bl strInsertAtCharInc
    bl affichageMess
    mov r0,#-1
    b 100f
93:                             @ control use all digits
    ldr r1,iAdriTabTopDigit
    mov r2,#0
94:                             @ begin loop
    ldr r0,[r1,r2,lsl #2]       @ load top
    cmp r0,#0
    bne 95f
    ldr r0,iAdrszMessNoalldigits
    bl affichageMess
    mov r0,#-1
    b 100f
95:
    add r2,r2,#1
    cmp r2,#NBDIGITS
    blt 94b
96:                             @ display message OK
    ldr r0,iAdrszMessOK
    bl affichageMess
    mov r0,#0
    b 100f

100:
    add sp,sp,#80               @ stack algnement
    pop {r1-r11,lr}
    bx lr                       @ return
iAdrszMessNoparen:        .int szMessNoparen
iAdrszMessNotOK:          .int szMessNotOK
iAdrszMessOK:             .int szMessOK
iAdrszMessNoalldigits:    .int szMessNoalldigits
/******************************************************************/
/*            depile operator                                     */
/******************************************************************/
/* r0 operator stack address  */
/* r1 digits stack address */
/* r2 operator indice */
/* r3 digits indice */
/* r4 operator */
/* r2 return a new operator indice */
/* r3 return a new digits indice */
depileOper:
    push {r4-r8,lr}        @ save registers
    cmp r2,#0              @ first operator ?
    beq 60f
    sub r5,r2,#1
1:
    ldr r6,[r0,r5,lsl #2]  @ load stack operator
    cmp r6,r4              @ same operators
    beq 50f
    cmp r6,#'*'            @ multiplication
    beq 50f
    cmp r6,#'/'            @ division
    beq 50f
    cmp r6,#'-'            @ soustraction
    beq 50f

    b 60f
50:                        @ depile operators stack and compute
    sub r2,r2,#1
    sub r3,r3,#1
    bl compute
    sub r5,r5,#1
    cmp r5,#0
    bge 1b
60:
    str r4,[r0,r2,lsl #2]  @ add operator in stack
    add r2,r2,#1

100:
    pop {r4-r8,lr}
    bx lr                  @ return
/******************************************************************/
/*            compute                                             */
/******************************************************************/
/* r0 operator stack address  */
/* r1 digits stack address */
/* r2 operator indice */
/* r3 digits indice */
compute:
    push {r1-r8,lr}        @ save registers
    ldr r6,[r1,r3,lsl #2]  @ load second digit
    sub r5,r3,#1
    ldr r7,[r1,r5,lsl #2]  @ load first digit

    ldr r8,[r0,r2,lsl #2]  @ load operator
    cmp r8,#'+'
    bne 1f
    add r7,r7,r6           @ addition
    str r7,[r1,r5,lsl #2]
    b 100f
1:
    cmp r8,#'-'
    bne 2f
    sub r7,r7,r6           @ soustaction
    str r7,[r1,r5,lsl #2]
    b 100f
2:
    cmp r8,#'*'
    bne 3f                 @ multiplication
    mul r7,r6,r7
    str r7,[r1,r5,lsl #2]
    b 100f
3:
    cmp r8,#'/'
    bne 4f
    udiv r7,r7,r6          @ division
    str r7,[r1,r5,lsl #2]
    b 100f
4:
    cmp r8,#'('            @ left parenthesis ?
    bne 5f
    ldr r0,iAdrszMessErrParen @  error
    bl affichageMess
    mov r0,#-1
    b 100f
5:
    ldr r0,iAdrszMessErrOper
    bl affichageMess
    mov r0,#-1
100:
    pop {r1-r8,lr}
    bx lr                   @ return
iAdrszMessErrOper:   .int szMessErrOper
iAdrszMessErrParen:  .int szMessErrParen
/******************************************************************/
/*            control digits                                       */
/******************************************************************/
/* r0 return 0 if OK 1 if  not digit   */
digitControl:
    push {r1-r4,lr}        @ save registers
    ldr r1,iAdriTabTopDigit
    ldr r2,iAdriTabDigit
    mov r3,#0
1:
    ldr r4,[r2,r3,lsl #2]  @ load digit
    cmp r0,r4              @ equal ?
    beq 2f                 @ yes
    add r3,r3,#1           @ no -> loop
    cmp r3,#NBDIGITS       @ end ?
    blt 1b
    ldr r0,iAdrszMessNoDigit @ error
    bl affichageMess
    mov r0,#1
    b 100f
2:                         @ control prev use
    ldr r4,[r1,r3,lsl #2]
    cmp r4,#0
    beq 3f
    add r3,r3,#1
    cmp r3,#NBDIGITS
    blt 1b
    ldr r0,iAdrszMessSameDigit
    bl affichageMess
    mov r0,#1
    b 100f
3:
    mov r4,#1
    str r4,[r1,r3,lsl #2]
    mov r0,#0
100:
    pop {r1-r4,lr}
    bx lr                   @ return
iAdrszMessNoDigit:     .int szMessNoDigit
iAdrszMessSameDigit:   .int szMessSameDigit
/******************************************************************/
/*            string entry                                       */
/******************************************************************/
/* r0 return the first character of human entry */
saisie:
    push {r1-r7,lr}        @ save registers
    mov r0,#STDIN          @ Linux input console
    ldr r1,iAdrsBuffer     @ buffer address
    mov r2,#BUFFERSIZE     @ buffer size
    mov r7,#READ           @ request to read datas
    svc 0                  @ call system
    ldr r1,iAdrsBuffer     @ buffer address
    ldrb r0,[r1]           @ load first character
100:
    pop {r1-r7,lr}
    bx lr                   @ return
iAdrsBuffer:         .int sBuffer
/***************************************************/
/*   Generation random number                  */
/***************************************************/
/* r0 contains limit  */
genereraleas:
    push {r1-r4,lr}         @ save registers
    ldr r4,iAdriGraine
    ldr r2,[r4]
    ldr r3,iNbDep1
    mul r2,r3,r2
    ldr r3,iNbDep2
    add r2,r2,r3
    str r2,[r4]             @ maj de la graine pour l appel suivant
    cmp r0,#0
    beq 100f
    add r1,r0,#1            @ divisor
    mov r0,r2               @ dividende
    bl division
    mov r0,r3               @ résult = remainder

100:                        @ end function
    pop {r1-r4,lr}          @ restaur registers
    bx lr                   @ return
/*****************************************************/
iAdriGraine: .int iGraine
iNbDep1:     .int 0x343FD
iNbDep2:     .int 0x269EC3
/***************************************************/
/*      ROUTINES INCLUDE                           */
/***************************************************/
.include "../affichage.inc"

24 Game
The program will display four randomly-generated
single-digit numbers and will then prompt you to enter
an arithmetic expression followed by <enter> to sum
the given numbers to 24.
Exemple : 9+8+3+4   or (7+5)+(3*4)

The four digits are 5 1 1 5 and the score is 24.
Enter your expression (or type (q)uit to exit or (n) for other digits):
n
The four digits are 8 2 5 3 and the score is 24.
Enter your expression (or type (q)uit to exit or (n) for other digits):
(8*2)+5+3
It is OK.

New game (y/n) ?

"Generate a game that randomly selects four digits and prompts the user to create an arithmetic expression with these digits that equals 24. The code checks and evaluates the user's expression, allowing for addition, subtraction, multiplication, and division operations. The code does not allow the formation of multiple digit numbers from the given digits."


Works with: as version Raspberry Pi
/* ARM assembly Raspberry PI  */
/*  program strConcat.s   */

/* Constantes    */
.equ STDOUT, 1                           @ Linux output console
.equ EXIT,   1                           @ Linux syscall
.equ WRITE,  4                           @ Linux syscall
/* Initialized data */
.data
szMessFinal:   .asciz "The final string is \n"

szString:            .asciz "Hello "
szString1:           .asciz " the world. \n"

/* UnInitialized data */
.bss
szFinalString:   .skip 255

/*  code section */
.text
.global main
main:
                                         @ load string
    ldr r1,iAdrszString
	ldr r2,iAdrszFinalString
    mov r4,#0
1:
    ldrb r0,[r1,r4]                      @ load byte of string
    strb r0,[r2,r4]
    cmp r0,#0                            @ compar with zero ?
    addne r4,#1
    bne 1b
    ldr r1,iAdrszString1
    mov r3,#0
2:
    ldrb r0,[r1,r3]                      @ load byte of string 1
    strb r0,[r2,r4]
    cmp r0,#0                            @ compar with zero ?
    addne r4,#1
    addne r3,#1
    bne 2b
    mov r0,r2                            @ display final string
    bl affichageMess
100:                                     @ standard end of the program */
    mov r0, #0                           @ return code
    mov r7, #EXIT                        @ request to exit program
    svc 0                                @ perform the system call
iAdrszString:             .int szString
iAdrszString1:            .int szString1
iAdrszFinalString:       .int szFinalString
iAdrszMessFinal:          .int szMessFinal

/******************************************************************/
/*     display text with size calculation                         */
/******************************************************************/
/* r0 contains the address of the message */
affichageMess:
    push {r0,r1,r2,r7,lr}                       @ save  registers
    mov r2,#0                                   @ counter length */
1:                                              @ loop length calculation
    ldrb r1,[r0,r2]                             @ read octet start position + index
    cmp r1,#0                                   @ if 0 its over
    addne r2,r2,#1                              @ else add 1 in the length
    bne 1b                                      @ and loop
                                                @ so here r2 contains the length of the message
    mov r1,r0                                   @ address message in r1
    mov r0,#STDOUT                              @ code to write to the standard output Linux
    mov r7, #WRITE                              @ code call system "write"
    svc #0                                      @ call systeme
    pop {r0,r1,r2,r7,lr}                        @ restaur des  2 registres
    bx lr                                       @ return

Initializes two string variables, one with a text value and the other as a concatenation of the first variable and a string literal, then displays their content.


Works with: as version Raspberry Pi  or android 32 bits with application Termux
/* ARM assembly Raspberry PI  */
/*  program anagram.s   */

 /* REMARK 1 : this program use routines in a include file
   see task Include a file language arm assembly
   for the routine affichageMess conversion10
   see at end of this program the instruction include */
/* for constantes see task include a file in arm assembly */
/************************************/
/* Constantes                       */
/************************************/
.include "../constantes.inc"

.equ MAXI,         40000
.equ BUFFERSIZE,   300000
.equ READ, 3                            @ system call
.equ OPEN, 5                            @ system call
.equ CLOSE, 6                           @ system call
.equ O_RDWR,  0x0002                    @ open for reading and writing

/*********************************/
/* Initialized data              */
/*********************************/
.data
szFileName:           .asciz "./listword.txt"
szMessErreur:         .asciz "FILE ERROR."
szCarriageReturn:     .asciz "\n"
szMessSpace:          .asciz " "

ptBuffer1:            .int sBuffer1
/*********************************/
/* UnInitialized data            */
/*********************************/
.bss
ptTabBuffer:                .skip 4 * MAXI
ptTabAna:                   .skip 4 * MAXI
tbiCptAna:                  .skip 4 * MAXI
iNBword:                    .skip 4
sBuffer:                    .skip BUFFERSIZE
sBuffer1:                   .skip BUFFERSIZE

/*********************************/
/*  code section                 */
/*********************************/
.text
.global main
main:                      @ entry of program
    mov r4,#0              @ loop indice
    ldr r0,iAdrszFileName  @ file name
    mov r1,#O_RDWR         @ flags
    mov r2,#0              @ mode
    mov r7,#OPEN           @
    svc 0
    cmp r0,#0              @ error open
    ble 99f
    mov r8,r0              @ FD save Fd
    ldr r1,iAdrsBuffer     @ buffer address
    ldr r2,iSizeBuf        @ buffersize
    mov r7, #READ
    svc 0
    cmp r0,#0              @ error read ?
    blt 99f
    mov r5,r0              @ save size read bytes
    ldr r4,iAdrsBuffer     @ buffer address
    ldr r0,iAdrsBuffer     @ start word address
    mov r2,#0
    mov r1,#0              @ word length
1:
    cmp r2,r5
    bge 2f
    ldrb r3,[r4,r2]
    cmp r3,#0xD            @ end word ?
    addne r1,r1,#1         @ increment word length
    addne r2,r2,#1         @ increment indice
    bne 1b                 @ and loop
    mov r3,#0
    strb r3,[r4,r2]        @ store final zero
    bl anaWord             @ sort word letters
    add r2,r2,#2           @ jump OD and 0A
    add r0,r4,r2           @ new address begin word
    mov r1,#0              @ init length
    b 1b                   @ and loop

2:
    mov r3,#0              @ last word
    strb r3,[r4,r2]
    bl anaWord

    mov r0,r8              @ file Fd
    mov r7, #CLOSE
    svc 0
    cmp r0,#0              @ error close ?
    blt 99f

    ldr r0,iAdrptTabAna    @ address sorted string area
    mov r1,#0              @ first indice
    ldr r2,iAdriNBword
    ldr r2,[r2]            @ last indice
    ldr r3,iAdrptTabBuffer @ address sorted string area
    bl triRapide           @ quick sort
    ldr r4,iAdrptTabAna    @ address sorted string area
    ldr r7,iAdrptTabBuffer @ address sorted string area
    ldr r10,iAdrtbiCptAna  @ address counter occurences
    mov r9,r2              @ size word array
    mov r8,#0              @ indice first occurence
    ldr r3,[r4,r8,lsl #2]  @ load first value
    mov r2,#1              @ loop indice
    mov r6,#0              @ counter
    mov r12,#0             @ counter value max
3:
    ldr r5,[r4,r2,lsl #2]  @ load next value
    mov r0,r3
    mov r1,r5
    bl comparStrings
    cmp r0,#0              @ sorted strings equal ?
    bne 4f
    add r6,r6,#1           @ yes increment counter
    b 5f
4:                         @ no
    str r6,[r10,r8,lsl #2] @ store counter in first occurence
    cmp r6,r12             @ counter > value max
    movgt r12,r6           @ yes  counter -> value max
    mov r6,#0              @ raz counter
    mov r8,r2              @ init index first occurence
    mov r3,r5              @ init value first occurence
5:
    add r2,r2,#1           @ increment indice
    cmp r2,r9              @ end word array ?
    blt 3b                 @ no -> loop

    mov r2,#0              @ raz indice
6:                         @ display loop
    ldr r6,[r10,r2,lsl #2] @ load counter
    cmp r6,r12             @ equal to max value ?
    bne 8f
    ldr r0,[r7,r2,lsl #2]  @ load address first word
    bl affichageMess
    add r3,r2,#1           @ increment new indixe
    mov r4,#0              @ counter
7:
    ldr r0,iAdrszMessSpace
    bl affichageMess
    ldr r0,[r7,r3,lsl #2]  @ load address other word
    bl affichageMess
    add r3,r3,#1           @ increment indice
    add r4,r4,#1           @ increment counter
    cmp r4,r6              @ max value ?
    blt 7b                 @ no loop
    ldr r0,iAdrszCarriageReturn
    bl affichageMess
8:
    add r2,r2,#1           @ increment indice
    cmp r2,r9              @ maxi ?
    blt 6b                 @ no -> loop

    b 100f
99:                        @ display error
    ldr r1,iAdrszMessErreur
    bl displayError

100:                       @ standard end of the program
    mov r0, #0             @ return code
    mov r7, #EXIT          @ request to exit program
    svc #0                 @ perform the system call
iAdrszCarriageReturn:        .int szCarriageReturn
iAdrszFileName:              .int szFileName
iAdrszMessErreur:            .int szMessErreur
iAdrsBuffer:                 .int sBuffer
iSizeBuf:                    .int BUFFERSIZE
iAdrszMessSpace:             .int szMessSpace
iAdrtbiCptAna:               .int tbiCptAna
/******************************************************************/
/*     analizing word                                   */
/******************************************************************/
/*  r0  word address */
/*  r1 word length   */
anaWord:
    push {r1-r6,lr}
    mov r5,r0
    mov r6,r1
    ldr r1,iAdrptTabBuffer
    ldr r2,iAdriNBword
    ldr r3,[r2]
    str r0,[r1,r3,lsl #2]

    ldr r1,iAdrptTabAna
    ldr r4,iAdrptBuffer1
    ldr r0,[r4]
    add r6,r6,r0
    add r6,r6,#1
    str r6,[r4]
    str r0,[r1,r3,lsl #2]

    add r3,r3,#1
    str r3,[r2]
    mov r1,r0
    mov r0,r5
    bl triLetters         @ sort word letters
    mov r2,#0
100:
    pop {r1-r6,pc}
iAdrptTabBuffer:        .int ptTabBuffer
iAdrptTabAna:           .int ptTabAna
iAdriNBword:            .int iNBword
iAdrptBuffer1:          .int ptBuffer1
/******************************************************************/
/*     sort word letters                                  */
/******************************************************************/
/* r0  address begin word */
/* r1  address recept array */
triLetters:
    push {r1-r7,lr}
    mov r2,#0
1:
    ldrb r3,[r0,r2]         @ load letter
    cmp r3,#0               @ end word ?
    beq 6f
    cmp r2,#0               @ first letter ?
    bne 2f
    strb r3,[r1,r2]         @ yes store in first position
    add r2,r2,#1            @ increment indice
    b 1b                    @ and loop
2:
    mov r4,#0
3:                          @ begin loop to search insertion position
    ldrb r5,[r1,r4]         @ load letter
    cmp r3,r5               @ compare
    blt 4f                  @ to low -> insertion
    add r4,r4,#1            @ increment indice
    cmp r4,r2               @ compare to letters number in place
    blt 3b                  @ search loop
    strb r3,[r1,r2]         @ else store in last position
    add r2,r2,#1
    b 1b                    @ and loop
4:                          @ move first letters in one position
    sub r6,r2,#1            @ start indice
5:
    ldrb r5,[r1,r6]         @ load letter
    add r7,r6,#1            @ store indice - 1
    strb r5,[r1,r7]         @ store letter
    sub r6,r6,#1            @ decrement indice
    cmp r6,r4               @ end ?
    bge 5b                  @ no loop
    strb r3,[r1,r4]         @ else store letter in free position
    add r2,r2,#1
    b 1b                    @ and loop
6:
    mov r3,#0               @ final zéro
    strb r3,[r1,r2]
100:
    pop {r1-r7,pc}
/***************************************************/
/*   Appel récursif Tri Rapide quicksort           */
/***************************************************/
/* r0 contains the address of table */
/* r1 contains index of first item  */
/* r2 contains the number of elements  > 0  */
/* r3 contains the address of table 2 */
triRapide:
    push {r2-r6,lr}         @ save registers
    mov r6,r3
    sub r2,#1               @ last item index
    cmp r1,r2               @ first > last ?
    bge 100f                @ yes -> end
    mov r4,r0               @ save r0
    mov r5,r2               @ save r2
    mov r3,r6
    bl partition1           @ cutting into 2 parts
    mov r2,r0               @ index partition
    mov r0,r4               @ table address
    bl triRapide            @ sort lower part
    mov r0,r4               @ table address
    add r1,r2,#1            @ index begin = index partition + 1
    add r2,r5,#1            @ number of elements
    bl triRapide            @ sort higter part

 100:                       @ end function
    pop {r2-r6,lr}          @ restaur  registers
    bx lr                   @ return

/******************************************************************/
/*      Partition table elements                                */
/******************************************************************/
/* r0 contains the address of table */
/* r1 contains index of first item  */
/* r2 contains index of last item   */
/* r3 contains the address of table 2 */
partition1:
    push {r1-r12,lr}        @ save registers
    mov r8,r0               @ save address table 2
    mov r9,r1
    ldr r10,[r8,r2,lsl #2]  @ load string address last index
    mov r4,r9               @ init with first index
    mov r5,r9               @ init with first index
1:                          @ begin loop
    ldr r6,[r8,r5,lsl #2]   @ load string address
    mov r0,r6
    mov r1,r10
    bl comparStrings
    cmp r0,#0
    ldrlt r7,[r8,r4,lsl #2]  @ if < swap value table
    strlt r6,[r8,r4,lsl #2]
    strlt r7,[r8,r5,lsl #2]
    ldrlt r7,[r3,r4,lsl #2]  @ swap array 2
    ldrlt r12,[r3,r5,lsl #2]
    strlt r7,[r3,r5,lsl #2]
    strlt r12,[r3,r4,lsl #2]
    addlt r4,#1              @ and increment index 1
    add    r5,#1             @ increment index 2
    cmp r5,r2                @ end ?
    blt 1b                   @ no -> loop
    ldr r7,[r8,r4,lsl #2]    @ swap value
    str r10,[r8,r4,lsl #2]
    str r7,[r8,r2,lsl #2]
    ldr r7,[r3,r4,lsl #2]    @ swap array 2
    ldr r12,[r3,r2,lsl #2]
    str r7,[r3,r2,lsl #2]
    str r12,[r3,r4,lsl #2]

    mov r0,r4                @ return index partition
100:
    pop {r1-r12,lr}
    bx lr
/************************************/
/* Strings case sensitive comparisons  */
/************************************/
/* r0 et r1 contains the address of strings */
/* return 0 in r0 if equals */
/* return -1 if string r0 < string r1 */
/* return 1  if string r0 > string r1 */
comparStrings:
    push {r1-r4}      @ save des registres
    mov r2,#0         @ counter
1:
    ldrb r3,[r0,r2]   @ byte string 1
    ldrb r4,[r1,r2]   @ byte string 2
    cmp r3,r4
    movlt r0,#-1      @ small
    movgt r0,#1       @ greather
    bne 100f          @ not equals
    cmp r3,#0         @ 0 end string
    moveq r0,#0       @ equals
    beq 100f          @ end string
    add r2,r2,#1      @ else add 1 in counter
    b 1b              @ and loop
100:
    pop {r1-r4}
    bx lr

/***************************************************/
/*      ROUTINES INCLUDE                           */
/***************************************************/
.include "../affichage.inc"
bale able bela abel elba
cater carte crate caret trace
galen glean angle lange angel
regal glare alger lager large
lena lane lean elan neal
veil levi live vile evil

"Code identifies sets of anagrams with the most words from the provided word list."