235 lines
9.4 KiB
Text
235 lines
9.4 KiB
Text
/* ARM assembly AARCH64 Raspberry PI 3B */
|
|
/* program rpg64.s */
|
|
|
|
/*******************************************/
|
|
/* Constantes file */
|
|
/*******************************************/
|
|
/* for this file see task include a file in language AArch64 assembly*/
|
|
.include "../includeConstantesARM64.inc"
|
|
|
|
.equ NBTIRAGES, 4
|
|
.equ NBTIRAGESOK, 3
|
|
.equ NBVALUES, 6
|
|
.equ TOTALMIN, 75
|
|
.equ MAXVALUE, 15
|
|
.equ NBMAXVALUE, 2
|
|
|
|
/*********************************/
|
|
/* Initialized data */
|
|
/*********************************/
|
|
.data
|
|
sMessResult: .asciz "Value = @ \n"
|
|
szCarriageReturn: .asciz "\n"
|
|
sMessResultT: .asciz "Total = @ \n"
|
|
sMessResultQ: .asciz "Values above 15 = @ \n"
|
|
|
|
|
|
.align 4
|
|
qGraine: .quad 123456789
|
|
|
|
/*********************************/
|
|
/* UnInitialized data */
|
|
/*********************************/
|
|
.bss
|
|
tqTirages: .skip 8 * NBTIRAGES
|
|
tqValues: .skip 8 * NBVALUES
|
|
|
|
sZoneConv: .skip 24
|
|
/*********************************/
|
|
/* code section */
|
|
/*********************************/
|
|
.text
|
|
.global main
|
|
main: // entry of program
|
|
|
|
1: // begin loop 1
|
|
mov x2,0 // counter value >15
|
|
mov x4,0 // loop indice
|
|
mov x5,0 // total
|
|
ldr x3,qAdrtqValues // table values address
|
|
2:
|
|
bl genValue // call generate value
|
|
str x0,[x3,x4,lsl 3] // store in table
|
|
add x5,x5,x0 // compute total
|
|
cmp x0,MAXVALUE // count value >= 15
|
|
add x6,x2,1
|
|
csel x2,x6,x2,ge
|
|
add x4,x4,1 // increment indice
|
|
cmp x4,NBVALUES // end ?
|
|
blt 2b
|
|
cmp x5,TOTALMIN // compare 75
|
|
blt 1b // < loop
|
|
cmp x2,#NBMAXVALUE // compare value > 15
|
|
blt 1b // < loop
|
|
ldr x0,qAdrtqValues // display values
|
|
bl displayTable
|
|
mov x0,x5 // total
|
|
|
|
ldr x1,qAdrsZoneConv // display value
|
|
bl conversion10 // call conversion decimal
|
|
ldr x0,qAdrsMessResultT
|
|
ldr x1,qAdrsZoneConv
|
|
bl strInsertAtCharInc // insert result at @ character
|
|
bl affichageMess // display message
|
|
|
|
mov x0,x2 // counter value > 15
|
|
ldr x1,qAdrsZoneConv // display value
|
|
bl conversion10 // call conversion decimal
|
|
ldr x0,qAdrsMessResultQ
|
|
ldr x1,qAdrsZoneConv
|
|
bl strInsertAtCharInc // insert result at @ character
|
|
bl affichageMess // display message
|
|
|
|
100: // standard end of the program
|
|
mov x0,0 // return code
|
|
mov x8,EXIT // request to exit program
|
|
svc 0 // perform the system call
|
|
|
|
qAdrsZoneConv: .quad sZoneConv
|
|
qAdrszCarriageReturn: .quad szCarriageReturn
|
|
qAdrsMessResult: .quad sMessResult
|
|
qAdrsMessResultT: .quad sMessResultT
|
|
qAdrsMessResultQ: .quad sMessResultQ
|
|
qAdrtqValues: .quad tqValues
|
|
/******************************************************************/
|
|
/* generate value */
|
|
/******************************************************************/
|
|
/* x0 returns the value */
|
|
genValue:
|
|
stp x1,lr,[sp,-16]! // save registers
|
|
stp x2,x3,[sp,-16]! // save registers
|
|
mov x3,0 // indice loop
|
|
ldr x1,qAdrtqTirages // table tirage address
|
|
1:
|
|
mov x0,6
|
|
bl genereraleas // result 0 to 5
|
|
add x0,x0,#1 // for 1 to 6
|
|
str x0,[x1,x3,lsl 3] // store tirage
|
|
add x3,x3,1 // increment indice
|
|
cmp x3,NBTIRAGES // end ?
|
|
blt 1b // no -> loop
|
|
ldr x0,qAdrtqTirages // table tirage address
|
|
mov x1,#0 // first item
|
|
mov x2,#NBTIRAGES // number of tirages
|
|
bl shellSort // sort table decreasing
|
|
mov x3,#0 // raz indice loop
|
|
mov x0,#0 // total
|
|
ldr x1,qAdrtqTirages // table tirage address
|
|
2:
|
|
ldr x2,[x1,x3,lsl 3] // read tirage
|
|
add x0,x0,x2 // compute sum
|
|
add x3,x3,1 // increment indice
|
|
cmp x3,NBTIRAGESOK // end ?
|
|
blt 2b
|
|
100:
|
|
ldp x2,x3,[sp],16 // restaur 2 registers
|
|
ldp x1,lr,[sp],16 // restaur 2 registers
|
|
ret // return to address lr x30
|
|
qAdrtqTirages: .quad tqTirages
|
|
/***************************************************/
|
|
/* shell Sort decreasing */
|
|
/***************************************************/
|
|
/* x0 contains the address of table */
|
|
/* x1 contains the first element but not use !! */
|
|
/* this routine use first element at index zero !!! */
|
|
/* x2 contains the number of element */
|
|
shellSort:
|
|
stp x1,lr,[sp,-16]! // save registers
|
|
stp x2,x3,[sp,-16]! // save registers
|
|
stp x4,x5,[sp,-16]! // save registers
|
|
stp x6,x7,[sp,-16]! // save registers
|
|
stp x8,x9,[sp,-16]! // save registers
|
|
sub x2,x2,1 // index last item
|
|
mov x1,x2 // init gap = last item
|
|
1: // start loop 1
|
|
lsr x1,x1,1 // gap = gap / 2
|
|
cbz x1,100f // if gap = 0 -> end
|
|
mov x3,x1 // init loop indice 1
|
|
2: // start loop 2
|
|
ldr x4,[x0,x3,lsl 3] // load first value
|
|
mov x5,x3 // init loop indice 2
|
|
3: // start loop 3
|
|
cmp x5,x1 // indice < gap
|
|
blt 4f // yes -> end loop 2
|
|
sub x6,x5,x1 // index = indice - gap
|
|
ldr x8,[x0,x6,lsl 3] // load second value
|
|
cmp x4,x8 // compare values
|
|
ble 4f
|
|
str x8,[x0,x5,lsl 3] // store if >
|
|
sub x5,x5,x1 // indice = indice - gap
|
|
b 3b // and loop
|
|
4: // end loop 3
|
|
str x4,[x0,x5,lsl 3] // store value 1 at indice 2
|
|
add x3,x3,1 // increment indice 1
|
|
cmp x3,x2 // end ?
|
|
ble 2b // no -> loop 2
|
|
b 1b // yes loop for new gap
|
|
|
|
100: // end function
|
|
ldp x8,x9,[sp],16 // restaur 2 registers
|
|
ldp x6,x7,[sp],16 // restaur 2 registers
|
|
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
|
|
|
|
/******************************************************************/
|
|
/* Display table elements */
|
|
/******************************************************************/
|
|
/* x0 contains the address of table */
|
|
displayTable:
|
|
stp x1,lr,[sp,-16]! // save registers
|
|
stp x2,x3,[sp,-16]! // save registers
|
|
mov x2,x0 // table address
|
|
mov x3,0
|
|
1: // loop display table
|
|
ldr x0,[x2,x3,lsl 3]
|
|
ldr x1,qAdrsZoneConv // display value
|
|
bl conversion10 // call function
|
|
ldr x0,qAdrsMessResult
|
|
ldr x1,qAdrsZoneConv
|
|
bl strInsertAtCharInc // insert result at @ character
|
|
bl affichageMess // display message
|
|
add x3,x3,1
|
|
cmp x3,NBVALUES - 1
|
|
ble 1b
|
|
ldr x0,qAdrszCarriageReturn
|
|
bl affichageMess
|
|
100:
|
|
ldp x2,x3,[sp],16 // restaur 2 registers
|
|
ldp x1,lr,[sp],16 // restaur 2 registers
|
|
ret // return to address lr x30
|
|
|
|
/***************************************************/
|
|
/* Generation random number */
|
|
/* algo xorshift (see wikipedia) */
|
|
/***************************************************/
|
|
/* x0 contains limit */
|
|
genereraleas:
|
|
stp x1,lr,[sp,-16]! // save registers
|
|
stp x2,x3,[sp,-16]! // save registers
|
|
cbz x0,100f
|
|
mov x3,x0 // maxi value
|
|
ldr x0,qAdrqGraine // graine
|
|
ldr x2,[x0]
|
|
lsl x1,x2,13
|
|
eor x2,x2,x1
|
|
lsr x1,x2,7
|
|
eor x2,x2,x1
|
|
lsl x1,x2,17
|
|
eor x1,x2,x1
|
|
str x1,[x0] // sauver graine
|
|
udiv x2,x1,x3 //
|
|
msub x0,x2,x3,x1 // compute result modulo limit
|
|
|
|
100: // end function
|
|
ldp x2,x3,[sp],16 // restaur 2 registers
|
|
ldp x1,lr,[sp],16 // restaur 2 registers
|
|
ret // return to address lr x30
|
|
/*****************************************************/
|
|
qAdrqGraine: .quad qGraine
|
|
/********************************************************/
|
|
/* File Include fonctions */
|
|
/********************************************************/
|
|
/* for this file see task include a file in language AArch64 assembly */
|
|
.include "../includeARM64.inc"
|