/* ARM assembly Raspberry PI */ /* program routstring.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 */ /*******************************************/ .include "../constantes.inc" .equ BUFFERSIZE, 80 /*******************************************/ /* macros */ /*******************************************/ //.include "../../ficmacros32.inc" @ for developper debugging /*********************************/ /* Initialized data */ /*********************************/ .data szMessDebutPgm: .asciz "Program 32 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 r0,iAdrszMessDebutPgm bl affichageMess @ start message ldr r0,iAdrszMessValString bl affichageMess ldr r0,iAdrszString1 bl affichageMess ldr r0,iAdrszCarriageReturn bl affichageMess ldr r0,iAdrszMessLenStr bl affichageMess mov r0,#LGSTRING1 @ string length static bl displayNumber ldr r0,iAdrszMessLenStr bl affichageMess ldr r0,iAdrszString1 bl stringLen @ string length bl displayNumber ldr r0,iAdrszString1 @ string copy ldr r1,iAdrszStringRec mov r2,#BUFFERSIZE bl copyString cmp r0,#-1 beq 100f ldr r0,iAdrszMessCopyString bl affichageMess ldr r0,iAdrszStringRec bl affichageMess ldr r0,iAdrszCarriageReturn bl affichageMess ldr r0,iAdrszString2 @ empty string bl emptyString ldr r0,iAdrszString1 @ string comparison ldr r0,iAdrszString3 bl comparString cmp r0,#0 bne 1f ldr r0,iAdrszMessStrEqual bl affichageMess b 2f 1: ldr r0,iAdrszMessStrNotEqual bl affichageMess 2: ldr r0,iAdrszString1 @ search substring ldr r1,iAdrszString4 bl searchSubString cmp r0,#-1 beq 3f mov r1,r0 ldr r0,iAdrszMessStringfound bl affichageMess mov r0,r1 bl displayNumber 3: ldr r0,iAdrszMessStringJoint @ joint strings bl affichageMess ldr r0,iAdrszString1 ldr r1,iAdrszString3 ldr r2,iAdrszStringRec mov r3,#BUFFERSIZE bl concatString cmp r0,#-1 beq 100f ldr r0,iAdrszStringRec bl affichageMess ldr r0,iAdrszCarriageReturn bl affichageMess ldr r0,iAdrszMessStringRep @ replace string or char bl affichageMess ldr r0,iAdrszString5 @ string ldr r1,iAdrszStringOcc @ string occurence ldr r2,iAdrszStringRep @ replace string ldr r3,iAdrszStringRec @ buffer mov r4,#BUFFERSIZE @ buffer size bl replaceOccString cmp r0,#-1 beq 100f ldr r0,iAdrszStringRec bl affichageMess ldr r0,iAdrszCarriageReturn bl affichageMess ldr r0,iAdrszMessFinOK bl affichageMess b 100f 99: ldr r0,iAdrszMessErreur @ error bl affichageMess mov r0, #1 @ return code error b 100f 100: mov r7,#EXIT @ program end svc #0 @ system call iAdrszMessDebutPgm: .int szMessDebutPgm iAdrszMessFinOK: .int szMessFinOK iAdrszMessErreur: .int szMessErreur iAdrsZoneConv: .int sZoneConv iAdrszMessLenStr: .int szMessLenStr iAdrszMessValString: .int szMessValString iAdrszMessCopyString: .int szMessCopyString iAdrszMessStrEqual: .int szMessStrEqual iAdrszMessStrNotEqual: .int szMessStrNotEqual iAdrszMessStringfound: .int szMessStringfound iAdrszMessStringJoint: .int szMessStringJoint iAdrszMessStringRep: .int szMessStringRep iAdrszString1: .int szString1 iAdrszString2: .int szString2 iAdrszString3: .int szString3 iAdrszString4: .int szString4 iAdrszString5: .int szString5 iAdrszStringRec: .int szStringRec iAdrszStringOcc: .int szStringOcc iAdrszStringRep: .int szStringRep /***************************************************/ /* String length */ /***************************************************/ /* r0 contains string address */ /* r0 returns length */ stringLen: push {r1,r2,lr} @ save registers mov r1,#0 @ byte counter 1: ldrb r2,[r0,r1] @ load byte cmp r2,#0 @ final zero ? moveq r0,r1 @ return counter beq 100f add r1,r1,#1 @ increment counter b 1b @ and loop 100: pop {r1,r2,pc} @ restaur registers /***************************************************/ /* empty String */ /***************************************************/ /* r0 contains string address */ /* r0 returns 0 if string empty */ emptyString: push {lr} @ save registers ldrb r0,[r0] @ load first byte cmp r0,#0 bne 100f ldr r0,iAdrszMessEmpty bl affichageMess mov r0,#0 100: pop {pc} @ restaur registers iAdrszMessEmpty: .int szMessEmpty /***************************************************/ /* String copy */ /***************************************************/ /* r0 contains string address */ /* r1 contains area string */ /* r2 contains area size */ copyString: push {r3-r5,lr} @ save registers mov r5,#0 @ indice 1: ldrb r3,[r0,r5] @ load byte strb r3,[r1,r5] @ store byte cmp r3,#0 @ final zero ? moveq r0,r5 beq 100f add r5,r5,#1 @ increment indice cmp r5,r2 @ > buffer size ? bge 99f @ error b 1b @ loop 99: ldr r0,iAdrszMessBufferError bl affichageMess mov r0,#-1 100: pop {r3-r5,pc} @ restaur registers /***************************************************/ /* display number */ /***************************************************/ /* r0 contains number */ displayNumber: push {r1,lr} @ save registers ldr r1,iAdrsZoneConv bl conversion10 ldr r0,iAdrsZoneConv bl affichageMess ldr r0,iAdrszCarriageReturn bl affichageMess 100: pop {r1,pc} @ restaur registers iAdrszCarriageReturn: .int szCarriageReturn /************************************/ /* String compare */ /************************************/ /* r0 et r1 contains strings address */ /* r0 returns 0 if equals -1 if less 1 if higter */ comparString: push {r1-r4} @ save registers mov r2,#0 @ indice 1: ldrb r3,[r0,r2] @ load byte string 1 ldrb r4,[r1,r2] @ load byte string 2 cmp r3,r4 movlt r0,#-1 @ less movgt r0,#1 @ hight bne 100f @ not equal cmp r3,#0 @ final zero ? moveq r0,#0 @ equal beq 100f @ and end add r2,r2,#1 @ increment indice b 1b @ and loop 100: pop {r1-r4} bx lr /******************************************************************/ /* search a substring in the string */ /******************************************************************/ /* r0 contains the address of the input string */ /* r1 contains the address of substring */ /* r0 returns index of substring in string or -1 if not found */ searchSubString: push {r1-r6,lr} @ save registers mov r2,#0 @ counter byte input string mov r3,#0 @ counter byte string mov r6,#-1 @ index found ldrb r4,[r1,r3] 1: ldrb r5,[r0,r2] @ load byte string cmp r5,#0 @ zero final ? moveq r0,#-1 @ yes returns error beq 100f cmp r5,r4 @ compare character beq 2f mov r6,#-1 @ no equals - > raz index mov r3,#0 @ and raz counter byte add r2,#1 @ and increment counter byte b 1b @ and loop 2: @ characters equals cmp r6,#-1 @ first characters equals ? moveq r6,r2 @ yes -> index begin in r6 add r3,#1 @ increment counter substring ldrb r4,[r1,r3] @ and load next byte cmp r4,#0 @ zero final ? beq 3f @ yes -> end search add r2,#1 @ else increment counter string b 1b @ and loop 3: mov r0,r6 100: pop {r1-r6,lr} @ restaur registers bx lr /******************************************************************/ /* joint strings */ /******************************************************************/ /* r0 and r1 contains strings address */ /* r2 contains address buffer */ /* r3 contains buffer length */ concatString: push {r3-r6,lr} @ save registers mov r6,#0 mov r5,#0 1: ldrb r4,[r0,r6] @ load byte string 1 cmp r4,#0 @ final zero ? beq 2f strb r4,[r2,r6] @ store byte in buffer add r6,r6,#1 @ increment indice cmp r6,r3 @ buffer max length ? bge 99f @ error b 1b @ else loop 2: ldrb r4,[r1,r5] @ load byte string 2 strb r4,[r2,r6] @ store byte in buffer cmp r4,#0 @ zero final ? beq 3f @ end add r6,r6,#1 @ increment indice cmp r6,r3 @ buffer max length ? bge 99f @ yes error add r5,r5,#1 @ else loop b 2b 3: mov r0,r6 b 100f 99: ldr r0,iAdrszMessBufferError bl affichageMess mov r0,#-1 100: pop {r3-r6,pc} @ restaur registers iAdrszMessBufferError: .int szMessBufferError /******************************************************************/ /* replace occurences strings */ /******************************************************************/ /* r0 string address */ /* r1 occurence string address */ /* r2 replace string address */ /* r3 contains address buffer */ /* r4 contains buffer length */ replaceOccString: push {r4-r6,lr} @ save registers mov r12,r0 mov r11,r1 mov r9,#0 @ indice string mov r6,#0 @ indice occurence mov r8,#0 @ indice write buffer mov r10,#-1 @ string occ start address 1: ldrb r0,[r11,r6] @ load search byte cmp r0,#0 @ final zero ? beq 3f 2: ldrb r7,[r12,r9] @ load string byte cmp r7,#0 @ zero final ? beq 6f cmp r0,r7 bne 4f @ if not equal cmp r10,#-1 @ string equal begin moveq r10,r9 @ string equal begin = string indice add r9,r9,#1 @ increment indice add r6,r6,#1 b 1b @ loop 3: @ end of strings equals mov r1,r8 bl replaceStr @ replace string cmp r0,#-1 @ error ? beq 99f mov r8,r0 mov r6,#0 @ raz indice search mov r10,#-1 @ raz string equal begin b 1b 4: @ bytes not equals cmp r10,#-1 @ if not string equal begin beq 5f 41: ldrb r0,[r12,r10] @ store bytes string strb r0,[r3,r8] add r8,r8,#1 cmp r8,r4 bge 99f add r10,r10,#1 cmp r10,r9 blt 41b mov r10,#-1 @ raz string equal begin mov r6,#0 @ raz indice occurence b 1b @ loop 5: @ byte not equal str r7,[r3,r8] @ store byte string in buffer add r8,r8,#1 cmp r8,r4 @ max buffer size ? bge 99f @ error add r9,r9,#1 @ inc indice chaine mov r6,#0 @ raz indice occ b 1b @ loop 6: @ end string ldrb r0,[r11,r6] @ load search byte cmp r0,#0 @ final zero bne 7f cmp r10,#-1 @ beq 100f mov r1,r8 bl replaceStr @ replace b 100f 7: cmp r10,#-1 @ pas de char en cours bne 8f mov r0,#0 strb r0,[r3,r8] @ final zero b 100f 8: ldrb r0,[r12,r10] @ load string byte strb r0,[r3,r8] @ store buffer byte add r8,r8,#1 cmp r8,r4 bge 99f add r10,r10,#1 @ increment begin string cmp r10,r9 @ compare with position string blt 8b @ loop mov r0,#0 strb r0,[r3,r8] @ final zero b 100f 99: @ buffer size error ldr r0,iAdrszMessBufferError bl affichageMess mov r0,#-1 100: pop {r4-r6,pc} /******************************************************************/ /* replace occurences strings */ /******************************************************************/ /* r0 string address */ /* r1 indice to replace */ /* r2 replace string address */ /* r3 contains address buffer */ /* r4 contains buffer length */ /* r0 return new buffer position */ replaceStr: push {r1-r6,lr} @ save registers mov r5,#0 1: ldrb r6,[r2,r5] @ load replace byte cmp r6,#0 @ final zero moveq r0,r1 beq 100f strb r6,[r3,r1] @ store byte in buffer add r1,r1,#1 cmp r1,r4 @ max size buffer ? bge 99f @ error add r5,r5,#1 b 1b 99: ldr r0,iAdrszMessBufferError bl affichageMess mov r0,#-1 100: pop {r1-r6,pc} /***************************************************/ /* ROUTINES INCLUDE */ /***************************************************/ .include "../affichage.inc"