354 lines
12 KiB
Plaintext
354 lines
12 KiB
Plaintext
/* 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"
|