/* ARM assembly AARCH64 Raspberry PI 3B */
/*  program josephus64.s   */
/* run with josephus64 maxi intervalle */
/* example : josephus64 41 3
 
/*******************************************/
/* Constantes file                         */
/*******************************************/
/* for this file see task include a file in language AArch64 assembly*/
.include "../includeConstantesARM64.inc"
 
.equ FIRSTNODE,        0              //identification first node 
 
/*******************************************/
/* Structures                               */
/********************************************/
/* structure linkedlist*/
    .struct  0
llist_next:                            // next element
    .struct  llist_next + 8
llist_value:                           // element value
    .struct  llist_value + 8
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  : josephus64 <maxi> <intervalle>\n"
/*********************************/
/* UnInitialized data            */
/*********************************/
.bss  
sZoneConv:         .skip 100
.align 4
qDebutListe1:       .skip llist_fin
/*********************************/
/*  code section                 */
/*********************************/
.text
.global main 
main:                                   // entry of program 
    mov fp,sp                           // copy stack address  register x29 fp
    ldr x0,qAdrszMessDebutPgm
    bl affichageMess
    ldr x0,[fp]                         // parameter number command line
    cmp x0,#2                           // correct ?
    ble erreurCommande                  // error
 
    add x0,fp,#16                       // address parameter 2
    ldr x0,[x0]
    bl conversionAtoD
    add x22,x0,FIRSTNODE                // save maxi
    add x0,fp,#24                       // address parameter 3
    ldr x0,[x0]
    bl conversionAtoD
    mov x21,x0                          // save gap
 
    mov x0,FIRSTNODE                    // create first node
    mov x1,0
    bl createNode
    mov x25,x0                          // first node address
    mov x26,x0
    mov x24,FIRSTNODE + 1
    mov x23,1
1:                                      // loop create others nodes
    mov x0,x24                          // key value
    mov x1,0
    bl createNode
    str x0,[x26,llist_next]             // store current node address in prev node
    mov x26,x0
    add x24,x24,1
    add x23,x23,1
    cmp x23,x22                         // maxi ?
    blt 1b
    str x25,[x26,llist_next]            // store first node address in last pointer
    mov x24,x26
2:
    mov x20,1                           // counter for gap
3:
    ldr x24,[x24,llist_next]
    add x20,x20,1
    cmp x20,x21                         // intervalle ?
    blt 3b
    ldr x25,[x24,llist_next]            // removing the node from the list
    ldr x22,[x25,llist_value]
    ldr x27,[x25,llist_next]            // load pointer next
    str x27,[x24,llist_next]            // ans store in prev node
    //mov x0,x25
    //bl displayNode
    cmp x27,x24
    csel x24,x24,x27,ne                 // next node address 
    bne 2b                              // and loop
 
    mov x0,x24
    bl displayNode                      // display last node
 
    b 100f
erreurCommande:
    ldr x0,qAdrszMessErrComm
    bl affichageMess
    mov x0,#1                          // error code
    b 100f
100:                                   // program end standard 
    ldr x0,qAdrszMessFinPgm
    bl affichageMess
    mov x0,0                          // return code Ok
    mov x8,EXIT                       // system call "Exit"
    svc #0
 
qAdrszMessDebutPgm:      .quad szMessDebutPgm
qAdrszMessFinPgm:        .quad szMessFinPgm
qAdrszRetourLigne:       .quad szRetourLigne
qAdrqDebutListe1:        .quad qDebutListe1
qAdrszMessErrComm:       .quad szMessErrComm
 
/******************************************************************/
/*     create node                                             */ 
/******************************************************************/
/* x0 contains key   */
/* x1 contains zero or address next node */
/* x0 returns address heap node  */
createNode:
    stp x20,lr,[sp,-16]!        // save  registres
    stp x21,x22,[sp,-16]!       // save  registres
    mov x20,x0                  // save key
    mov x21,x1                  // save key
    mov x0,#0                   // allocation place heap
    mov x8,BRK                  // call system 'brk'
    svc #0
    mov x22,x0                  // save address heap for node
    add x0,x0,llist_fin         // reservation place node length
    mov x8,BRK                  // call system 'brk'
    svc #0
    cmp x0,#-1                  // allocation error
    beq 100f
 
    str x20,[x22,llist_value]
    str x21,[x22,llist_next]
    mov x0,x22
100:
    ldp x21,x22,[sp],16         // restaur des  2 registres
    ldp x20,lr,[sp],16          // restaur des  2 registres
    ret                         // retour adresse lr x30
 
/******************************************************************/
/*     display infos node                                     */ 
/******************************************************************/
/* x0 contains node address */
displayNode:
    stp x1,lr,[sp,-16]!        // save  registres
    stp x2,x3,[sp,-16]!        // save  registres
    mov x2,x0
    ldr x1,qAdrsZoneConv
    bl conversion16
    ldr x0,qAdrszMessImpElement
    ldr x1,qAdrsZoneConv
    bl strInsertAtCharInc
    mov x3,x0
    ldr x0,[x2,llist_value]
    ldr x1,qAdrsZoneConv
    bl conversion10S
    mov x0,x3
    ldr x1,qAdrsZoneConv
    bl strInsertAtCharInc
    mov x3,x0
    ldr x0,[x2,llist_next]
    ldr x1,qAdrsZoneConv
    bl conversion16
    mov x0,x3
    ldr x1,qAdrsZoneConv
    bl strInsertAtCharInc
    bl affichageMess
 
100:
    ldp x2,x3,[sp],16          // restaur des  2 registres
    ldp x1,lr,[sp],16          // restaur des  2 registres
    ret                        // retour adresse lr x30
qAdrsZoneConv:               .quad sZoneConv
qAdrszMessImpElement:        .quad szMessImpElement
/********************************************************/
/*        File Include fonctions                        */
/********************************************************/
/* for this file see task include a file in language AArch64 assembly */
.include "../includeARM64.inc"

Josephus Problem