/* ARM assembly AARCH64 Raspberry PI 3B */ /* program Ycombi64.s */ /*******************************************/ /* Constantes file */ /*******************************************/ /* for this file see task include a file in language AArch64 assembly*/ .include "../includeConstantesARM64.inc" /*******************************************/ /* Structures */ /********************************************/ /* structure function*/ .struct 0 func_fn: // next element .struct func_fn + 8 func_f_: // next element .struct func_f_ + 8 func_num: .struct func_num + 8 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 : @ \n" /* UnInitialized data */ .bss sZoneConv: .skip 100 /* code section */ .text .global main main: // program start ldr x0,qAdrszMessStartPgm // display start message bl affichageMess adr x0,facFunc // function factorielle address bl YFunc // create Ycombinator mov x19,x0 // save Ycombinator ldr x0,qAdrszFactorielle // display message bl affichageMess mov x20,#1 // loop counter 1: // start loop mov x0,x20 bl numFunc // create number structure cmp x0,#-1 // allocation error ? beq 99f mov x1,x0 // structure number address mov x0,x19 // Ycombinator address bl callFunc // call ldr x0,[x0,#func_num] // load result ldr x1,qAdrsZoneConv // and convert ascii string bl conversion10S // decimal conversion ldr x0,qAdrszMessResult ldr x1,qAdrsZoneConv bl strInsertAtCharInc // insert result at @ character bl affichageMess // display message final add x20,x20,#1 // increment loop counter cmp x20,#10 // end ? ble 1b // no -> loop /*********Fibonacci *************/ adr x0,fibFunc // function fibonacci address bl YFunc // create Ycombinator mov x19,x0 // save Ycombinator ldr x0,qAdrszFibonacci // display message bl affichageMess mov x20,#1 // loop counter 2: // start loop mov x0,x20 bl numFunc // create number structure cmp x0,#-1 // allocation error ? beq 99f mov x1,x0 // structure number address mov x0,x19 // Ycombinator address bl callFunc // call ldr x0,[x0,#func_num] // load result ldr x1,qAdrsZoneConv // and convert ascii string bl conversion10S ldr x0,qAdrszMessResult ldr x1,qAdrsZoneConv bl strInsertAtCharInc // insert result at @ character bl affichageMess add x20,x20,#1 // increment loop counter cmp x20,#10 // end ? ble 2b // no -> loop ldr x0,qAdrszMessEndPgm // display end message bl affichageMess b 100f 99: // display error message ldr x0,qAdrszMessError bl affichageMess 100: // standard end of the program mov x0,0 // return code mov x8,EXIT // request to exit program svc 0 // perform system call qAdrszMessStartPgm: .quad szMessStartPgm qAdrszMessEndPgm: .quad szMessEndPgm qAdrszFactorielle: .quad szFactorielle qAdrszFibonacci: .quad szFibonacci qAdrszMessError: .quad szMessError qAdrszCarriageReturn: .quad szCarriageReturn qAdrszMessResult: .quad szMessResult qAdrsZoneConv: .quad sZoneConv /******************************************************************/ /* factorielle function */ /******************************************************************/ /* x0 contains the Y combinator address */ /* x1 contains the number structure */ facFunc: stp x1,lr,[sp,-16]! // save registers stp x2,x3,[sp,-16]! // save registers mov x2,x0 // save Y combinator address ldr x0,[x1,#func_num] // load number cmp x0,#1 // > 1 ? bgt 1f // yes mov x0,#1 // create structure number value 1 bl numFunc b 100f 1: mov x3,x0 // save number sub x0,x0,#1 // decrement number bl numFunc // and create new structure number cmp x0,#-1 // allocation error ? beq 100f mov x1,x0 // new structure number -> param 1 ldr x0,[x2,#func_f_] // load function address to execute bl callFunc // call ldr x1,[x0,#func_num] // load new result mul x0,x1,x3 // and multiply by precedent bl numFunc // and create new structure number // and return her address in x0 100: ldp x2,x3,[sp],16 // restaur 2 registers ldp x1,lr,[sp],16 // restaur 2 registers ret // return to address lr x30 /******************************************************************/ /* fibonacci function */ /******************************************************************/ /* x0 contains the Y combinator address */ /* x1 contains the number structure */ fibFunc: stp x1,lr,[sp,-16]! // save registers stp x2,x3,[sp,-16]! // save registers stp x4,x5,[sp,-16]! // save registers mov x2,x0 // save Y combinator address ldr x0,[x1,#func_num] // load number cmp x0,#1 // > 1 ? bgt 1f // yes mov x0,#1 // create structure number value 1 bl numFunc b 100f 1: mov x3,x0 // save number sub x0,x0,#1 // decrement number bl numFunc // and create new structure number cmp x0,#-1 // allocation error ? beq 100f mov x1,x0 // new structure number -> param 1 ldr x0,[x2,#func_f_] // load function address to execute bl callFunc // call ldr x4,[x0,#func_num] // load new result sub x0,x3,#2 // new number - 2 bl numFunc // and create new structure number cmp x0,#-1 // allocation error ? beq 100f mov x1,x0 // new structure number -> param 1 ldr x0,[x2,#func_f_] // load function address to execute bl callFunc // call ldr x1,[x0,#func_num] // load new result add x0,x1,x4 // add two results bl numFunc // and create new structure number // and return her address in x0 100: ldp x4,x5,[sp],16 // restaur 2 registers ldp x2,x3,[sp],16 // restaur 2 registers ldp x1,lr,[sp],16 // restaur 2 registers ret // return to address lr x30 /******************************************************************/ /* call function */ /******************************************************************/ /* x0 contains the address of the function */ /* x1 contains the address of the function 1 */ callFunc: stp x2,lr,[sp,-16]! // save registers ldr x2,[x0,#func_fn] // load function address to execute blr x2 // and call it ldp x2,lr,[sp],16 // restaur 2 registers ret // return to address lr x30 /******************************************************************/ /* create Y combinator function */ /******************************************************************/ /* x0 contains the address of the function */ YFunc: stp x1,lr,[sp,-16]! // save registers mov x1,#0 bl newFunc cmp x0,#-1 // allocation error ? beq 100f str x0,[x0,#func_f_] // store function and return in x0 100: ldp x1,lr,[sp],16 // restaur 2 registers ret // return to address lr x30 /******************************************************************/ /* create structure number function */ /******************************************************************/ /* x0 contains the number */ numFunc: stp x1,lr,[sp,-16]! // save registers stp x2,x3,[sp,-16]! // save registers mov x2,x0 // save number mov x0,#0 // function null mov x1,#0 // function null bl newFunc cmp x0,#-1 // allocation error ? beq 100f str x2,[x0,#func_num] // store number in new structure 100: ldp x2,x3,[sp],16 // restaur 2 registers ldp x1,lr,[sp],16 // restaur 2 registers ret // return to address lr x30 /******************************************************************/ /* new function */ /******************************************************************/ /* x0 contains the function address */ /* x1 contains the function address 1 */ newFunc: stp x1,lr,[sp,-16]! // save registers stp x3,x4,[sp,-16]! // save registers stp x5,x8,[sp,-16]! // save registers mov x4,x0 // save address mov x5,x1 // save adresse 1 // allocation place on the heap mov x0,#0 // allocation place heap mov x8,BRK // call system 'brk' svc #0 mov x6,x0 // save address heap for output string add x0,x0,#func_fin // reservation place one element mov x8,BRK // call system 'brk' svc #0 cmp x0,#-1 // allocation error beq 100f mov x0,x6 str x4,[x0,#func_fn] // store address str x5,[x0,#func_f_] str xzr,[x0,#func_num] // store zero to number 100: ldp x5,x8,[sp],16 // restaur 2 registers ldp x3,x4,[sp],16 // restaur 2 registers ldp x1,lr,[sp],16 // restaur 2 registers ret // return to address lr x30 /********************************************************/ /* File Include fonctions */ /********************************************************/ /* for this file see task include a file in language AArch64 assembly */ .include "../includeARM64.inc"