/* ARM assembly AARCH64 Raspberry PI 3B */ /* program routstring64.s */ /*******************************************/ /* Constantes */ /*******************************************/ /* for this file see task include a file in language AArch64 assembly*/ .include "../includeConstantesARM64.inc" .equ BUFFERSIZE, 80 /*******************************************/ /* macros */ /*******************************************/ //.include "../../ficmacros64.inc" // for developper debugging /*********************************/ /* Initialized data */ /*********************************/ .data szMessDebutPgm: .asciz "Program 64 bits start. \n" szCarriageReturn: .asciz "\n" szMessFinOK: .asciz "Program normal end. \n" szMessErreur: .asciz "Error !!!\n" szMessValString: .asciz "String value : " szMessLenStr: .asciz "String length : " szMessCopyString: .asciz "String copy : " szMessEmpty: .asciz "String empty.\n" szMessStrEqual: .asciz "Strings are equals.\n" szMessStrNotEqual: .asciz "Strings are not equals.\n" szMessStringfound: .asciz "String found at position :" szMessStringJoint: .asciz "Joint string : " szMessStringRep: .asciz "Replace occurences string : " szMessBufferError: .asciz "Error : Buffer too small !!\n" szString1: .asciz "ABCDE" .equ LGSTRING1, . - szString1 - 1 szString2: .asciz "" szString3: .asciz "ABCDF" szString4: .asciz "CD" szString5: .asciz "AABCIEFAAGHIAA" szStringOcc: .asciz "AA" szStringRep: .asciz "ZZ" .align 4 /*********************************/ /* UnInitialized data */ /*********************************/ .bss sZoneConv: .skip 24 szStringRec: .skip BUFFERSIZE .align 4 /*********************************/ /* code section */ /*********************************/ .text .global main main: ldr x0,qAdrszMessDebutPgm bl affichageMess // start message ldr x0,qAdrszMessValString bl affichageMess ldr x0,qAdrszString1 bl affichageMess ldr x0,qAdrszCarriageReturn bl affichageMess ldr x0,qAdrszMessLenStr bl affichageMess mov x0,#LGSTRING1 // string length static bl displayNumber ldr x0,qAdrszMessLenStr bl affichageMess ldr x0,qAdrszString1 bl stringLen // string length bl displayNumber ldr x0,qAdrszString1 // string copy ldr x1,qAdrszStringRec mov x2,#BUFFERSIZE bl copyString cmp x0,#-1 beq 100f ldr x0,qAdrszMessCopyString bl affichageMess ldr x0,qAdrszStringRec bl affichageMess ldr x0,qAdrszCarriageReturn bl affichageMess ldr x0,qAdrszString2 // empty string bl emptyString ldr x0,qAdrszString1 // string comparison ldr x0,qAdrszString3 bl comparString cmp x0,#0 bne 1f ldr x0,qAdrszMessStrEqual bl affichageMess b 2f 1: ldr x0,qAdrszMessStrNotEqual bl affichageMess 2: ldr x0,qAdrszString1 // search substring ldr x1,qAdrszString4 bl searchSubString cmp x0,#-1 beq 3f mov x1,x0 ldr x0,qAdrszMessStringfound bl affichageMess mov x0,x1 bl displayNumber 3: ldr x0,qAdrszMessStringJoint // joint strings bl affichageMess ldr x0,qAdrszString1 ldr x1,qAdrszString3 ldr x2,qAdrszStringRec mov x3,#BUFFERSIZE bl concatString cmp x0,#-1 beq 100f ldr x0,qAdrszStringRec bl affichageMess ldr x0,qAdrszCarriageReturn bl affichageMess ldr x0,qAdrszMessStringRep // replace string or char bl affichageMess ldr x0,qAdrszString5 // string ldr x1,qAdrszStringOcc // string occurence ldr x2,qAdrszStringRep // replace string ldr x3,qAdrszStringRec // buffer mov x4,#BUFFERSIZE // buffer size bl replaceOccString cmp x0,#-1 beq 100f ldr x0,qAdrszStringRec bl affichageMess ldr x0,qAdrszCarriageReturn bl affichageMess ldr x0,qAdrszMessFinOK bl affichageMess b 100f 99: ldr x0,qAdrszMessErreur // error bl affichageMess mov x0, #1 // return code error b 100f 100: mov x8,EXIT svc #0 // system call qAdrszMessDebutPgm: .quad szMessDebutPgm qAdrszMessFinOK: .quad szMessFinOK qAdrszMessErreur: .quad szMessErreur qAdrsZoneConv: .quad sZoneConv qAdrszMessLenStr: .quad szMessLenStr qAdrszMessValString: .quad szMessValString qAdrszMessCopyString: .quad szMessCopyString qAdrszMessStrEqual: .quad szMessStrEqual qAdrszMessStrNotEqual: .quad szMessStrNotEqual qAdrszMessStringfound: .quad szMessStringfound qAdrszMessStringJoint: .quad szMessStringJoint qAdrszMessStringRep: .quad szMessStringRep qAdrszString1: .quad szString1 qAdrszString2: .quad szString2 qAdrszString3: .quad szString3 qAdrszString4: .quad szString4 qAdrszString5: .quad szString5 qAdrszStringRec: .quad szStringRec qAdrszStringOcc: .quad szStringOcc qAdrszStringRep: .quad szStringRep /***************************************************/ /* String length */ /***************************************************/ /* x0 contains string address */ /* x0 returns length */ stringLen: stp x1,lr,[sp,-16]! // stp x2,x3,[sp,-16]! mov x1,#0 // byte counter 1: ldrb w2,[x0,x1] // load byte cmp x2,#0 // final zero ? csel x0,x1,x0,eq // return counter beq 100f add x1,x1,#1 // increment counter b 1b // and loop 100: ldp x2,x3,[sp],16 ldp x1,lr,[sp],16 ret /***************************************************/ /* empty String */ /***************************************************/ /* x0 contains string address */ /* x0 returns 0 if string empty */ emptyString: stp x1,lr,[sp,-16]! ldrb w0,[x0] // load first byte cmp x0,#0 bne 100f ldr x0,qAdrszMessEmpty bl affichageMess mov x0,#0 100: ldp x1,lr,[sp],16 ret qAdrszMessEmpty: .quad szMessEmpty /***************************************************/ /* String copy */ /***************************************************/ /* x0 contains string address */ /* x1 contains area string */ /* x2 contains area size */ copyString: stp x1,lr,[sp,-16]! stp x2,x3,[sp,-16]! stp x4,x5,[sp,-16]! mov x5,#0 // indice 1: ldrb w3,[x0,x5] // load byte strb w3,[x1,x5] // store byte cmp x3,#0 // final zero ? csel x0,x5,x0,eq beq 100f add x5,x5,#1 // increment indice cmp x5,x2 // > buffer size ? bge 99f // error b 1b // loop 99: ldr x0,qAdrszMessBufferError bl affichageMess mov x0,#-1 100: ldp x4,x5,[sp],16 ldp x2,x3,[sp],16 ldp x1,lr,[sp],16 ret /***************************************************/ /* display number */ /***************************************************/ /* x0 contains number */ displayNumber: stp x1,lr,[sp,-16]! // TODO: a completer ldr x1,qAdrsZoneConv bl conversion10 ldr x0,qAdrsZoneConv bl affichageMess ldr x0,qAdrszCarriageReturn bl affichageMess 100: ldp x1,lr,[sp],16 // TODO: a completer ret qAdrszCarriageReturn: .quad szCarriageReturn /************************************/ /* String compare */ /************************************/ /* x0 et x1 contains strings address */ /* x0 returns 0 if equals -1 if less 1 if higter */ comparString: stp x1,lr,[sp,-16]! stp x2,x3,[sp,-16]! stp x4,x5,[sp,-16]! mov x2,#0 // indice 1: ldrb w3,[x0,x2] // load byte string 1 ldrb w4,[x1,x2] // load byte string 2 cmp x3,x4 blt 2f bgt 3f cmp x3,#0 // final zero ? csel x0,xzr,x0,eq // equal beq 100f // and end add x2,x2,#1 // increment indice b 1b // and loop 2: mov x0,#-1 // less b 100f 3: // higt mov x0,#1 100: ldp x4,x5,[sp],16 ldp x2,x3,[sp],16 ldp x1,lr,[sp],16 ret /******************************************************************/ /* search a substring in the string */ /******************************************************************/ /* x0 contains the address of the input string */ /* x1 contains the address of substring */ /* x0 returns index of substring in string or -1 if not found */ searchSubString: stp x1,lr,[sp,-16]! stp x2,x3,[sp,-16]! stp x4,x5,[sp,-16]! stp x6,x7,[sp,-16]! mov x2,#0 // counter byte input string mov x3,#0 // counter byte string mov x6,#-1 // index found ldrb w4,[x1,x3] 1: ldrb w5,[x0,x2] // load byte string cmp x5,#0 // zero final ? mov x7,-1 csel x0,x7,x0,eq // yes returns error beq 100f cmp x5,x4 // compare character beq 2f mov x6,#-1 // no equals - > raz index mov x3,#0 // and raz counter byte add x2,x2,#1 // and increment counter byte b 1b // and loop 2: // characters equals cmp x6,#-1 // first characters equals ? csel x6,x2,x6,eq // yes -> index begin in r6 add x3,x3,#1 // increment counter substring ldrb w4,[x1,x3] // and load next byte cmp x4,#0 // zero final ? beq 3f // yes -> end search add x2,x2,#1 // else increment counter string b 1b // and loop 3: mov x0,x6 100: ldp x6,x7,[sp],16 ldp x4,x5,[sp],16 ldp x2,x3,[sp],16 ldp x1,lr,[sp],16 ret /******************************************************************/ /* joint strings */ /******************************************************************/ /* x0 and x1 contains strings address */ /* x2 contains address buffer */ /* x3 contains buffer length */ concatString: stp x1,lr,[sp,-16]! stp x2,x3,[sp,-16]! stp x4,x5,[sp,-16]! stp x6,x7,[sp,-16]! mov x6,#0 mov x5,#0 1: ldrb w4,[x0,x6] // load byte string 1 cmp x4,#0 // final zero ? beq 2f strb w4,[x2,x6] // store byte in buffer add x6,x6,#1 // increment indice cmp x6,x3 // buffer max length ? bge 99f // error b 1b // else loop 2: ldrb w4,[x1,x5] // load byte string 2 strb w4,[x2,x6] // store byte in buffer cmp x4,#0 // zero final ? beq 3f // end add x6,x6,#1 // increment indice cmp x6,x3 // buffer max length ? bge 99f // yes error add x5,x5,#1 // else loop b 2b 3: mov x0,x6 b 100f 99: ldr x0,qAdrszMessBufferError bl affichageMess mov x0,#-1 100: ldp x6,x7,[sp],16 ldp x4,x5,[sp],16 ldp x2,x3,[sp],16 ldp x1,lr,[sp],16 ret qAdrszMessBufferError: .quad szMessBufferError /******************************************************************/ /* replace occurences strings */ /******************************************************************/ /* x0 string address */ /* x1 occurence string address */ /* x2 replace string address */ /* x3 contains address buffer */ /* x4 contains buffer length */ replaceOccString: stp x1,lr,[sp,-16]! // TODO: a completer stp x2,x3,[sp,-16]! stp x4,x5,[sp,-16]! stp x6,x7,[sp,-16]! stp x8,x9,[sp,-16]! stp x10,x11,[sp,-16]! mov x12,x0 mov x11,x1 mov x9,#0 // indice string mov x6,#0 // indice occurence mov x8,#0 // indice write buffer mov x10,#-1 // string occ start address 1: ldrb w0,[x11,x6] // load search byte cmp x0,#0 // final zero ? beq 3f 2: ldrb w7,[x12,x9] // load string byte cmp x7,#0 // zero final ? beq 6f cmp x0,x7 bne 4f // if not equal cmp x10,#-1 // string equal begin csel x10,x9,x10,eq // string equal begin = string indice add x9,x9,#1 // increment indice add x6,x6,#1 b 1b // loop 3: // end of strings equals mov x1,x8 bl replaceStr // replace string cmp x0,#-1 // error ? beq 99f mov x8,x0 mov x6,#0 // raz indice search mov x10,#-1 // raz string equal begin b 1b 4: // bytes not equals cmp x10,#-1 // if not string equal begin beq 5f 41: ldrb w0,[x12,x10] // store bytes string strb w0,[x3,x8] add x8,x8,#1 cmp x8,x4 bge 99f add x10,x10,#1 cmp x10,x9 blt 41b mov x10,#-1 // raz string equal begin mov x6,#0 // raz indice occurence b 1b // loop 5: // byte not equal str x7,[x3,x8] // store byte string in buffer add x8,x8,#1 cmp x8,x4 // max buffer size ? bge 99f // error add x9,x9,#1 // inc indice chaine mov x6,#0 // raz indice occ b 1b // loop 6: // end string ldrb w0,[x11,x6] // load search byte cmp x0,#0 // final zero bne 7f cmp x10,#-1 // beq 100f mov x1,x8 bl replaceStr // replace b 100f 7: cmp x10,#-1 // pas de char en cours bne 8f mov x0,#0 strb w0,[x3,x8] // final zero b 100f 8: ldrb w0,[x12,x10] // load string byte strb w0,[x3,x8] // store buffer byte add x8,x8,#1 cmp x8,x4 bge 99f add x10,x10,#1 // increment begin string cmp x10,x9 // compare with position string blt 8b // loop mov x0,#0 strb w0,[x3,x8] // final zero b 100f 99: // buffer size error ldr x0,qAdrszMessBufferError bl affichageMess mov x0,#-1 100: ldp x10,x11,[sp],16 ldp x8,x9,[sp],16 ldp x6,x7,[sp],16 ldp x4,x5,[sp],16 ldp x2,x3,[sp],16 ldp x1,lr,[sp],16 // TODO: a completer ret /******************************************************************/ /* replace occurences strings */ /******************************************************************/ /* x0 string address */ /* x1 indice to replace */ /* x2 replace string address */ /* x3 contains address buffer */ /* x4 contains buffer length */ /* x0 return new buffer position */ replaceStr: stp x1,lr,[sp,-16]! // TODO: a completer stp x5,x6,[sp,-16]! mov x5,#0 1: ldrb w6,[x2,x5] // load replace byte cmp x6,#0 // final zero csel x0,x1,x0,eq beq 100f strb w6,[x3,x1] // store byte in buffer add x1,x1,#1 cmp x1,x4 // max size buffer ? bge 99f // error add x5,x5,#1 b 1b 99: ldr x0,qAdrszMessBufferError bl affichageMess mov x0,#-1 100: ldp x5,x6,[sp],16 ldp x1,lr,[sp],16 // TODO: a completer ret /***************************************************/ /* ROUTINES INCLUDE */ /***************************************************/ /* for this file see task include a file in language AArch64 assembly*/ .include "../includeARM64.inc"