/* ARM assembly Raspberry PI */ /* program anagram.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 */ /* for constantes see task include a file in arm assembly */ /************************************/ /* Constantes */ /************************************/ .include "../constantes.inc" .equ MAXI, 40000 .equ BUFFERSIZE, 300000 .equ READ, 3 @ system call .equ OPEN, 5 @ system call .equ CLOSE, 6 @ system call .equ O_RDWR, 0x0002 @ open for reading and writing /*********************************/ /* Initialized data */ /*********************************/ .data szFileName: .asciz "./listword.txt" szMessErreur: .asciz "FILE ERROR." szCarriageReturn: .asciz "\n" szMessSpace: .asciz " " ptBuffer1: .int sBuffer1 /*********************************/ /* UnInitialized data */ /*********************************/ .bss ptTabBuffer: .skip 4 * MAXI ptTabAna: .skip 4 * MAXI tbiCptAna: .skip 4 * MAXI iNBword: .skip 4 sBuffer: .skip BUFFERSIZE sBuffer1: .skip BUFFERSIZE /*********************************/ /* code section */ /*********************************/ .text .global main main: @ entry of program mov r4,#0 @ loop indice ldr r0,iAdrszFileName @ file name mov r1,#O_RDWR @ flags mov r2,#0 @ mode mov r7,#OPEN @ svc 0 cmp r0,#0 @ error open ble 99f mov r8,r0 @ FD save Fd ldr r1,iAdrsBuffer @ buffer address ldr r2,iSizeBuf @ buffersize mov r7, #READ svc 0 cmp r0,#0 @ error read ? blt 99f mov r5,r0 @ save size read bytes ldr r4,iAdrsBuffer @ buffer address ldr r0,iAdrsBuffer @ start word address mov r2,#0 mov r1,#0 @ word length 1: cmp r2,r5 bge 2f ldrb r3,[r4,r2] cmp r3,#0xD @ end word ? addne r1,r1,#1 @ increment word length addne r2,r2,#1 @ increment indice bne 1b @ and loop mov r3,#0 strb r3,[r4,r2] @ store final zero bl anaWord @ sort word letters add r2,r2,#2 @ jump OD and 0A add r0,r4,r2 @ new address begin word mov r1,#0 @ init length b 1b @ and loop 2: mov r3,#0 @ last word strb r3,[r4,r2] bl anaWord mov r0,r8 @ file Fd mov r7, #CLOSE svc 0 cmp r0,#0 @ error close ? blt 99f ldr r0,iAdrptTabAna @ address sorted string area mov r1,#0 @ first indice ldr r2,iAdriNBword ldr r2,[r2] @ last indice ldr r3,iAdrptTabBuffer @ address sorted string area bl triRapide @ quick sort ldr r4,iAdrptTabAna @ address sorted string area ldr r7,iAdrptTabBuffer @ address sorted string area ldr r10,iAdrtbiCptAna @ address counter occurences mov r9,r2 @ size word array mov r8,#0 @ indice first occurence ldr r3,[r4,r8,lsl #2] @ load first value mov r2,#1 @ loop indice mov r6,#0 @ counter mov r12,#0 @ counter value max 3: ldr r5,[r4,r2,lsl #2] @ load next value mov r0,r3 mov r1,r5 bl comparStrings cmp r0,#0 @ sorted strings equal ? bne 4f add r6,r6,#1 @ yes increment counter b 5f 4: @ no str r6,[r10,r8,lsl #2] @ store counter in first occurence cmp r6,r12 @ counter > value max movgt r12,r6 @ yes counter -> value max mov r6,#0 @ raz counter mov r8,r2 @ init index first occurence mov r3,r5 @ init value first occurence 5: add r2,r2,#1 @ increment indice cmp r2,r9 @ end word array ? blt 3b @ no -> loop mov r2,#0 @ raz indice 6: @ display loop ldr r6,[r10,r2,lsl #2] @ load counter cmp r6,r12 @ equal to max value ? bne 8f ldr r0,[r7,r2,lsl #2] @ load address first word bl affichageMess add r3,r2,#1 @ increment new indixe mov r4,#0 @ counter 7: ldr r0,iAdrszMessSpace bl affichageMess ldr r0,[r7,r3,lsl #2] @ load address other word bl affichageMess add r3,r3,#1 @ increment indice add r4,r4,#1 @ increment counter cmp r4,r6 @ max value ? blt 7b @ no loop ldr r0,iAdrszCarriageReturn bl affichageMess 8: add r2,r2,#1 @ increment indice cmp r2,r9 @ maxi ? blt 6b @ no -> loop b 100f 99: @ display error ldr r1,iAdrszMessErreur bl displayError 100: @ standard end of the program mov r0, #0 @ return code mov r7, #EXIT @ request to exit program svc #0 @ perform the system call iAdrszCarriageReturn: .int szCarriageReturn iAdrszFileName: .int szFileName iAdrszMessErreur: .int szMessErreur iAdrsBuffer: .int sBuffer iSizeBuf: .int BUFFERSIZE iAdrszMessSpace: .int szMessSpace iAdrtbiCptAna: .int tbiCptAna /******************************************************************/ /* analizing word */ /******************************************************************/ /* r0 word address */ /* r1 word length */ anaWord: push {r1-r6,lr} mov r5,r0 mov r6,r1 ldr r1,iAdrptTabBuffer ldr r2,iAdriNBword ldr r3,[r2] str r0,[r1,r3,lsl #2] ldr r1,iAdrptTabAna ldr r4,iAdrptBuffer1 ldr r0,[r4] add r6,r6,r0 add r6,r6,#1 str r6,[r4] str r0,[r1,r3,lsl #2] add r3,r3,#1 str r3,[r2] mov r1,r0 mov r0,r5 bl triLetters @ sort word letters mov r2,#0 100: pop {r1-r6,pc} iAdrptTabBuffer: .int ptTabBuffer iAdrptTabAna: .int ptTabAna iAdriNBword: .int iNBword iAdrptBuffer1: .int ptBuffer1 /******************************************************************/ /* sort word letters */ /******************************************************************/ /* r0 address begin word */ /* r1 address recept array */ triLetters: push {r1-r7,lr} mov r2,#0 1: ldrb r3,[r0,r2] @ load letter cmp r3,#0 @ end word ? beq 6f cmp r2,#0 @ first letter ? bne 2f strb r3,[r1,r2] @ yes store in first position add r2,r2,#1 @ increment indice b 1b @ and loop 2: mov r4,#0 3: @ begin loop to search insertion position ldrb r5,[r1,r4] @ load letter cmp r3,r5 @ compare blt 4f @ to low -> insertion add r4,r4,#1 @ increment indice cmp r4,r2 @ compare to letters number in place blt 3b @ search loop strb r3,[r1,r2] @ else store in last position add r2,r2,#1 b 1b @ and loop 4: @ move first letters in one position sub r6,r2,#1 @ start indice 5: ldrb r5,[r1,r6] @ load letter add r7,r6,#1 @ store indice - 1 strb r5,[r1,r7] @ store letter sub r6,r6,#1 @ decrement indice cmp r6,r4 @ end ? bge 5b @ no loop strb r3,[r1,r4] @ else store letter in free position add r2,r2,#1 b 1b @ and loop 6: mov r3,#0 @ final zéro strb r3,[r1,r2] 100: pop {r1-r7,pc} /***************************************************/ /* Appel récursif Tri Rapide quicksort */ /***************************************************/ /* r0 contains the address of table */ /* r1 contains index of first item */ /* r2 contains the number of elements > 0 */ /* r3 contains the address of table 2 */ triRapide: push {r2-r6,lr} @ save registers mov r6,r3 sub r2,#1 @ last item index cmp r1,r2 @ first > last ? bge 100f @ yes -> end mov r4,r0 @ save r0 mov r5,r2 @ save r2 mov r3,r6 bl partition1 @ cutting into 2 parts mov r2,r0 @ index partition mov r0,r4 @ table address bl triRapide @ sort lower part mov r0,r4 @ table address add r1,r2,#1 @ index begin = index partition + 1 add r2,r5,#1 @ number of elements bl triRapide @ sort higter part 100: @ end function pop {r2-r6,lr} @ restaur registers bx lr @ return /******************************************************************/ /* Partition table elements */ /******************************************************************/ /* r0 contains the address of table */ /* r1 contains index of first item */ /* r2 contains index of last item */ /* r3 contains the address of table 2 */ partition1: push {r1-r12,lr} @ save registers mov r8,r0 @ save address table 2 mov r9,r1 ldr r10,[r8,r2,lsl #2] @ load string address last index mov r4,r9 @ init with first index mov r5,r9 @ init with first index 1: @ begin loop ldr r6,[r8,r5,lsl #2] @ load string address mov r0,r6 mov r1,r10 bl comparStrings cmp r0,#0 ldrlt r7,[r8,r4,lsl #2] @ if < swap value table strlt r6,[r8,r4,lsl #2] strlt r7,[r8,r5,lsl #2] ldrlt r7,[r3,r4,lsl #2] @ swap array 2 ldrlt r12,[r3,r5,lsl #2] strlt r7,[r3,r5,lsl #2] strlt r12,[r3,r4,lsl #2] addlt r4,#1 @ and increment index 1 add r5,#1 @ increment index 2 cmp r5,r2 @ end ? blt 1b @ no -> loop ldr r7,[r8,r4,lsl #2] @ swap value str r10,[r8,r4,lsl #2] str r7,[r8,r2,lsl #2] ldr r7,[r3,r4,lsl #2] @ swap array 2 ldr r12,[r3,r2,lsl #2] str r7,[r3,r2,lsl #2] str r12,[r3,r4,lsl #2] mov r0,r4 @ return index partition 100: pop {r1-r12,lr} bx lr /************************************/ /* Strings case sensitive comparisons */ /************************************/ /* r0 et r1 contains the address of strings */ /* return 0 in r0 if equals */ /* return -1 if string r0 < string r1 */ /* return 1 if string r0 > string r1 */ comparStrings: push {r1-r4} @ save des registres mov r2,#0 @ counter 1: ldrb r3,[r0,r2] @ byte string 1 ldrb r4,[r1,r2] @ byte string 2 cmp r3,r4 movlt r0,#-1 @ small movgt r0,#1 @ greather bne 100f @ not equals cmp r3,#0 @ 0 end string moveq r0,#0 @ equals beq 100f @ end string add r2,r2,#1 @ else add 1 in counter b 1b @ and loop 100: pop {r1-r4} bx lr /***************************************************/ /* ROUTINES INCLUDE */ /***************************************************/ .include "../affichage.inc"