199 lines
6.6 KiB
Plaintext
199 lines
6.6 KiB
Plaintext
/* ARM assembly AARCH64 Raspberry PI 3B */
|
|
/* ARM assembly Raspberry PI */
|
|
/* program josephus.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
|
|
.equ BRK, 0x2d @ Linux syscall
|
|
.equ CHARPOS, '@'
|
|
|
|
.equ FIRSTNODE, 0 //identification first node
|
|
|
|
/*******************************************/
|
|
/* Structures */
|
|
/********************************************/
|
|
/* structure linkedlist*/
|
|
.struct 0
|
|
llist_next: // next element
|
|
.struct llist_next + 4
|
|
llist_value: // element value
|
|
.struct llist_value + 4
|
|
llist_fin:
|
|
/*********************************/
|
|
/* Initialized data */
|
|
/*********************************/
|
|
.data
|
|
szMessDebutPgm: .asciz "Start program.\n"
|
|
szMessFinPgm: .asciz "Program End ok.\n"
|
|
szRetourLigne: .asciz "\n"
|
|
szMessValElement: .asciz "Value : @ \n"
|
|
szMessListeVide: .asciz "List empty.\n"
|
|
szMessImpElement: .asciz "Node display: @ Value : @ Next @ \n"
|
|
szMessErrComm: .asciz "Incomplete Command line : josephus <maxi> <intervalle>\n"
|
|
/*********************************/
|
|
/* UnInitialized data */
|
|
/*********************************/
|
|
.bss
|
|
sZoneConv: .skip 24
|
|
.align 4
|
|
qDebutListe1: .skip llist_fin
|
|
/*********************************/
|
|
/* code section */
|
|
/*********************************/
|
|
.text
|
|
.global main
|
|
main: // entry of program
|
|
mov fp,sp // copy stack address register r29 fp
|
|
ldr r0,iAdrszMessDebutPgm
|
|
bl affichageMess
|
|
ldr r0,[fp] // parameter number command line
|
|
cmp r0,#2 // correct ?
|
|
ble erreurCommande // error
|
|
|
|
add r0,fp,#8 // address parameter 2
|
|
ldr r0,[r0]
|
|
bl conversionAtoD
|
|
add r2,r0,#FIRSTNODE // save maxi
|
|
add r0,fp,#12 // address parameter 3
|
|
ldr r0,[r0]
|
|
bl conversionAtoD
|
|
mov r8,r0 // save gap
|
|
|
|
mov r0,#FIRSTNODE // create first node
|
|
mov r1,#0
|
|
bl createNode
|
|
mov r5,r0 // first node address
|
|
mov r6,r0
|
|
mov r4,#FIRSTNODE + 1
|
|
mov r3,#1
|
|
1: // loop create others nodes
|
|
mov r0,r4 // key value
|
|
mov r1,#0
|
|
bl createNode
|
|
str r0,[r6,#llist_next] // store current node address in prev node
|
|
mov r6,r0
|
|
add r4,r4,#1
|
|
add r3,r3,#1
|
|
cmp r3,r2 // maxi ?
|
|
blt 1b
|
|
str r5,[r6,#llist_next] // store first node address in last pointer
|
|
mov r4,r6
|
|
2:
|
|
mov r2,#1 // counter for gap
|
|
3:
|
|
ldr r4,[r4,#llist_next]
|
|
add r2,r2,#1
|
|
cmp r2,r8 // intervalle ?
|
|
blt 3b
|
|
ldr r5,[r4,#llist_next] // removing the node from the list
|
|
ldr r2,[r5,#llist_value]
|
|
ldr r7,[r5,#llist_next] // load pointer next
|
|
str r7,[r4,#llist_next] // ans store in prev node
|
|
//mov r0,r25
|
|
//bl displayNode
|
|
cmp r7,r4
|
|
moveq r4,r7
|
|
bne 2b // and loop
|
|
|
|
mov r0,r4
|
|
bl displayNode // display last node
|
|
|
|
b 100f
|
|
erreurCommande:
|
|
ldr r0,iAdrszMessErrComm
|
|
bl affichageMess
|
|
mov r0,#1 // error code
|
|
b 100f
|
|
100: // program end standard
|
|
ldr r0,iAdrszMessFinPgm
|
|
bl affichageMess
|
|
mov r0,#0 // return code Ok
|
|
mov r7,#EXIT // system call "Exit"
|
|
svc #0
|
|
|
|
iAdrszMessDebutPgm: .int szMessDebutPgm
|
|
iAdrszMessFinPgm: .int szMessFinPgm
|
|
iAdrszRetourLigne: .int szRetourLigne
|
|
iAdrqDebutListe1: .int qDebutListe1
|
|
iAdrszMessErrComm: .int szMessErrComm
|
|
|
|
/******************************************************************/
|
|
/* create node */
|
|
/******************************************************************/
|
|
/* r0 contains key */
|
|
/* r1 contains zero or address next node */
|
|
/* r0 returns address heap node */
|
|
createNode:
|
|
push {r1-r11,lr} // save registers
|
|
mov r9,r0 // save key
|
|
mov r10,r1 // save key
|
|
mov r0,#0 // allocation place heap
|
|
mov r7,#BRK // call system 'brk'
|
|
svc #0
|
|
mov r11,r0 // save address heap for node
|
|
add r0,r0,#llist_fin // reservation place node length
|
|
mov r7,#BRK // call system 'brk'
|
|
svc #0
|
|
cmp r0,#-1 // allocation error
|
|
beq 100f
|
|
|
|
str r9,[r11,#llist_value]
|
|
str r10,[r11,#llist_next]
|
|
mov r0,r11
|
|
100:
|
|
pop {r1-r11,lr} // restaur registers
|
|
bx lr // return
|
|
|
|
/******************************************************************/
|
|
/* display infos node */
|
|
/******************************************************************/
|
|
/* r0 contains node address */
|
|
displayNode:
|
|
push {r1-r4,lr} // save registers
|
|
mov r2,r0
|
|
ldr r1,iAdrsZoneConv
|
|
bl conversion16
|
|
mov r4,#0
|
|
strb r4,[r1,r0] // store zero final
|
|
ldr r0,iAdrszMessImpElement
|
|
ldr r1,iAdrsZoneConv
|
|
bl strInsertAtCharInc
|
|
mov r3,r0
|
|
ldr r0,[r2,#llist_value]
|
|
ldr r1,iAdrsZoneConv
|
|
bl conversion10S
|
|
mov r4,#0
|
|
strb r4,[r1,r0] // store zero final
|
|
mov r0,r3
|
|
ldr r1,iAdrsZoneConv
|
|
bl strInsertAtCharInc
|
|
mov r3,r0
|
|
ldr r0,[r2,#llist_next]
|
|
ldr r1,iAdrsZoneConv
|
|
bl conversion16
|
|
mov r4,#0
|
|
strb r4,[r1,#8] // store zero final
|
|
mov r0,r3
|
|
ldr r1,iAdrsZoneConv
|
|
bl strInsertAtCharInc
|
|
bl affichageMess
|
|
|
|
100:
|
|
pop {r1-r4,lr} // restaur registers
|
|
bx lr // return
|
|
iAdrsZoneConv: .int sZoneConv
|
|
iAdrszMessImpElement: .int szMessImpElement
|
|
/***************************************************/
|
|
/* ROUTINES INCLUDE */
|
|
/***************************************************/
|
|
.include "../affichage.inc"
|