RosettaCodeData/Task/Amicable-pairs/ARM-Assembly/amicable-pairs.arm
2023-07-01 13:44:08 -04:00

151 lines
5.4 KiB
Text

/* ARM assembly Raspberry PI or android with termux */
/* program amicable.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 NMAXI, 20000
.equ TABMAXI, 100
/*********************************/
/* Initialized data */
/*********************************/
.data
sMessResult: .asciz " @ : @\n"
szCarriageReturn: .asciz "\n"
szMessErr1: .asciz "Array too small !!"
/*********************************/
/* UnInitialized data */
/*********************************/
.bss
sZoneConv: .skip 24
tResult: .skip 4 * TABMAXI
/*********************************/
/* code section */
/*********************************/
.text
.global main
main: @ entry of program
ldr r3,iNMaxi @ load limit
mov r4,#2 @ number begin
1:
mov r0,r4 @ number
bl decFactor @ compute sum factors
cmp r0,r4 @ equal ?
beq 2f
mov r2,r0 @ factor sum 1
bl decFactor
cmp r0,r4 @ equal number ?
bne 2f
mov r0,r4 @ yes -> search in array
mov r1,r2 @ and store sum
bl searchRes
cmp r0,#0 @ find ?
bne 2f @ yes
mov r0,r4 @ no -> display number ans sum
mov r1,r2
bl displayResult
2:
add r4,#1 @ increment number
cmp r4,r3 @ end ?
ble 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
iNMaxi: .int NMAXI
/***************************************************/
/* display message number */
/***************************************************/
/* r0 contains number 1 */
/* r1 contains number 2 */
displayResult:
push {r1-r3,lr} @ save registers
mov r2,r1
ldr r1,iAdrsZoneConv
bl conversion10 @ call décimal conversion
ldr r0,iAdrsMessResult
ldr r1,iAdrsZoneConv @ insert conversion in message
bl strInsertAtCharInc
mov r3,r0
mov r0,r2
ldr r1,iAdrsZoneConv
bl conversion10 @ call décimal conversion
mov r0,r3
ldr r1,iAdrsZoneConv @ insert conversion in message
bl strInsertAtCharInc
bl affichageMess @ display message
pop {r1-r3,pc} @ restaur des registres
iAdrsMessResult: .int sMessResult
iAdrsZoneConv: .int sZoneConv
/***************************************************/
/* compute factors sum */
/***************************************************/
/* r0 contains the number */
decFactor:
push {r1-r5,lr} @ save registers
mov r5,#1 @ init sum
mov r4,r0 @ save number
mov r1,#2 @ start factor -> divisor
1:
mov r0,r4 @ dividende
bl division
cmp r1,r2 @ divisor > quotient ?
bgt 3f
cmp r3,#0 @ remainder = 0 ?
bne 2f
add r5,r5,r1 @ add divisor to sum
cmp r1,r2 @ divisor = quotient ?
beq 3f @ yes -> end
add r5,r5,r2 @ no -> add quotient to sum
2:
add r1,r1,#1 @ increment factor
b 1b @ and loop
3:
mov r0,r5 @ return sum
pop {r1-r5,pc} @ restaur registers
/***************************************************/
/* search and store result in array */
/***************************************************/
/* r0 contains the number */
/* r1 contains factors sum */
/* r0 return 1 if find 0 else -1 if error */
searchRes:
push {r1-r4,lr} @ save registers
ldr r4,iAdrtResult @ array address
mov r2,#0 @ indice begin
1:
ldr r3,[r4,r2,lsl #2] @ load one result array
cmp r3,#0 @ if 0 store new result
beq 2f
cmp r3,r0 @ equal ?
moveq r0,#1 @ find -> return 1
beq 100f
add r2,r2,#1 @ increment indice
cmp r2,#TABMAXI @ maxi array ?
blt 1b
ldr r0,iAdrszMessErr1 @ error
bl affichageMess
mov r0,#-1
b 100f
2:
str r1,[r4,r2,lsl #2]
mov r0,#0 @ not find -> store and retun 0
100:
pop {r1-r4,pc} @ restaur registers
iAdrtResult: .int tResult
iAdrszMessErr1: .int szMessErr1
/***************************************************/
/* ROUTINES INCLUDE */
/***************************************************/
.include "../affichage.inc"