/* 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"