/* ARM assembly Raspberry PI */ /* program Ycombi.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 */ /* Constantes */ .equ STDOUT, 1 @ Linux output console .equ EXIT, 1 @ Linux syscall .equ WRITE, 4 @ Linux syscall /*******************************************/ /* Structures */ /********************************************/ /* structure function*/ .struct 0 func_fn: @ next element .struct func_fn + 4 func_f_: @ next element .struct func_f_ + 4 func_num: .struct func_num + 4 func_fin: /* Initialized data */ .data szMessStartPgm: .asciz "Program start \n" szMessEndPgm: .asciz "Program normal end.\n" szMessError: .asciz "\033[31mError Allocation !!!\n" szFactorielle: .asciz "Function factorielle : \n" szFibonacci: .asciz "Function Fibonacci : \n" szCarriageReturn: .asciz "\n" /* datas message display */ szMessResult: .ascii "Result value :" sValue: .space 12,' ' .asciz "\n" /* UnInitialized data */ .bss /* code section */ .text .global main main: @ program start ldr r0,iAdrszMessStartPgm @ display start message bl affichageMess adr r0,facFunc @ function factorielle address bl YFunc @ create Ycombinator mov r5,r0 @ save Ycombinator ldr r0,iAdrszFactorielle @ display message bl affichageMess mov r4,#1 @ loop counter 1: @ start loop mov r0,r4 bl numFunc @ create number structure cmp r0,#-1 @ allocation error ? beq 99f mov r1,r0 @ structure number address mov r0,r5 @ Ycombinator address bl callFunc @ call ldr r0,[r0,#func_num] @ load result ldr r1,iAdrsValue @ and convert ascii string bl conversion10 ldr r0,iAdrszMessResult @ display result message bl affichageMess add r4,#1 @ increment loop counter cmp r4,#10 @ end ? ble 1b @ no -> loop /*********Fibonacci *************/ adr r0,fibFunc @ function factorielle address bl YFunc @ create Ycombinator mov r5,r0 @ save Ycombinator ldr r0,iAdrszFibonacci @ display message bl affichageMess mov r4,#1 @ loop counter 2: @ start loop mov r0,r4 bl numFunc @ create number structure cmp r0,#-1 @ allocation error ? beq 99f mov r1,r0 @ structure number address mov r0,r5 @ Ycombinator address bl callFunc @ call ldr r0,[r0,#func_num] @ load result ldr r1,iAdrsValue @ and convert ascii string bl conversion10 ldr r0,iAdrszMessResult @ display result message bl affichageMess add r4,#1 @ increment loop counter cmp r4,#10 @ end ? ble 2b @ no -> loop ldr r0,iAdrszMessEndPgm @ display end message bl affichageMess b 100f 99: @ display error message ldr r0,iAdrszMessError bl affichageMess 100: @ standard end of the program mov r0, #0 @ return code mov r7, #EXIT @ request to exit program svc 0 @ perform system call iAdrszMessStartPgm: .int szMessStartPgm iAdrszMessEndPgm: .int szMessEndPgm iAdrszFactorielle: .int szFactorielle iAdrszFibonacci: .int szFibonacci iAdrszMessError: .int szMessError iAdrszCarriageReturn: .int szCarriageReturn iAdrszMessResult: .int szMessResult iAdrsValue: .int sValue /******************************************************************/ /* factorielle function */ /******************************************************************/ /* r0 contains the Y combinator address */ /* r1 contains the number structure */ facFunc: push {r1-r3,lr} @ save registers mov r2,r0 @ save Y combinator address ldr r0,[r1,#func_num] @ load number cmp r0,#1 @ > 1 ? bgt 1f @ yes mov r0,#1 @ create structure number value 1 bl numFunc b 100f 1: mov r3,r0 @ save number sub r0,#1 @ decrement number bl numFunc @ and create new structure number cmp r0,#-1 @ allocation error ? beq 100f mov r1,r0 @ new structure number -> param 1 ldr r0,[r2,#func_f_] @ load function address to execute bl callFunc @ call ldr r1,[r0,#func_num] @ load new result mul r0,r1,r3 @ and multiply by precedent bl numFunc @ and create new structure number @ and return her address in r0 100: pop {r1-r3,lr} @ restaur registers bx lr @ return /******************************************************************/ /* fibonacci function */ /******************************************************************/ /* r0 contains the Y combinator address */ /* r1 contains the number structure */ fibFunc: push {r1-r4,lr} @ save registers mov r2,r0 @ save Y combinator address ldr r0,[r1,#func_num] @ load number cmp r0,#1 @ > 1 ? bgt 1f @ yes mov r0,#1 @ create structure number value 1 bl numFunc b 100f 1: mov r3,r0 @ save number sub r0,#1 @ decrement number bl numFunc @ and create new structure number cmp r0,#-1 @ allocation error ? beq 100f mov r1,r0 @ new structure number -> param 1 ldr r0,[r2,#func_f_] @ load function address to execute bl callFunc @ call ldr r4,[r0,#func_num] @ load new result sub r0,r3,#2 @ new number - 2 bl numFunc @ and create new structure number cmp r0,#-1 @ allocation error ? beq 100f mov r1,r0 @ new structure number -> param 1 ldr r0,[r2,#func_f_] @ load function address to execute bl callFunc @ call ldr r1,[r0,#func_num] @ load new result add r0,r1,r4 @ add two results bl numFunc @ and create new structure number @ and return her address in r0 100: pop {r1-r4,lr} @ restaur registers bx lr @ return /******************************************************************/ /* call function */ /******************************************************************/ /* r0 contains the address of the function */ /* r1 contains the address of the function 1 */ callFunc: push {r2,lr} @ save registers ldr r2,[r0,#func_fn] @ load function address to execute blx r2 @ and call it pop {r2,lr} @ restaur registers bx lr @ return /******************************************************************/ /* create Y combinator function */ /******************************************************************/ /* r0 contains the address of the function */ YFunc: push {r1,lr} @ save registers mov r1,#0 bl newFunc cmp r0,#-1 @ allocation error ? strne r0,[r0,#func_f_] @ store function and return in r0 pop {r1,lr} @ restaur registers bx lr @ return /******************************************************************/ /* create structure number function */ /******************************************************************/ /* r0 contains the number */ numFunc: push {r1,r2,lr} @ save registers mov r2,r0 @ save number mov r0,#0 @ function null mov r1,#0 @ function null bl newFunc cmp r0,#-1 @ allocation error ? strne r2,[r0,#func_num] @ store number in new structure pop {r1,r2,lr} @ restaur registers bx lr @ return /******************************************************************/ /* new function */ /******************************************************************/ /* r0 contains the function address */ /* r1 contains the function address 1 */ newFunc: push {r2-r7,lr} @ save registers mov r4,r0 @ save address mov r5,r1 @ save adresse 1 @ allocation place on the heap mov r0,#0 @ allocation place heap mov r7,#0x2D @ call system 'brk' svc #0 mov r3,r0 @ save address heap for output string add r0,#func_fin @ reservation place one element mov r7,#0x2D @ call system 'brk' svc #0 cmp r0,#-1 @ allocation error beq 100f mov r0,r3 str r4,[r0,#func_fn] @ store address str r5,[r0,#func_f_] mov r2,#0 str r2,[r0,#func_num] @ store zero to number 100: pop {r2-r7,lr} @ restaur registers bx lr @ return /***************************************************/ /* ROUTINES INCLUDE */ /***************************************************/ .include "../affichage.inc"