RosettaCodeData/Task/Abbreviations-easy/ARM-Assembly/abbreviations-easy.arm
2023-07-01 13:44:08 -04:00

387 lines
12 KiB
Text

/* ARM assembly Raspberry PI */
/* program abbrEasy.s */
/* store list of command in a file */
/* and run the program abbrEasy command.file */
/* 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 STDIN, 0 @ Linux input console
.equ STDOUT, 1 @ Linux output console
.equ EXIT, 1 @ Linux syscall
.equ READ, 3 @ Linux syscall
.equ WRITE, 4 @ Linux syscall
.equ OPEN, 5 @ Linux syscall
.equ CLOSE, 6 @ Linux syscall
.equ O_RDWR, 0x0002 @ open for reading and writing
.equ SIZE, 4
.equ NBBOX, SIZE * SIZE
.equ BUFFERSIZE, 1000
.equ NBMAXIELEMENTS, 100
/*********************************/
/* Initialized data */
/*********************************/
.data
szMessTitre: .asciz "Nom du fichier : "
szCarriageReturn: .asciz "\n"
szMessErreur: .asciz "Error detected.\n"
szMessErrBuffer: .asciz "buffer size too less !!"
szMessErrorAbr: .asciz "*error*"
szMessInput: .asciz "Enter command (or quit to stop) : "
szCmdQuit: .asciz "QUIT"
szValTest1: .asciz "Quit"
szValTest2: .asciz "Rep"
/*********************************/
/* UnInitialized data */
/*********************************/
.bss
.align 4
sZoneConv: .skip 24
iAdrFicName: .skip 4
iTabAdrCmd: .skip 4 * NBMAXIELEMENTS
sBufferCmd: .skip BUFFERSIZE
sBuffer: .skip BUFFERSIZE
/*********************************/
/* code section */
/*********************************/
.text
.global main
main: @ INFO: main
mov r0,sp @ stack address for load parameter
bl traitFic @ read file and store value in array
cmp r0,#-1
beq 100f @ error ?
ldr r0,iAdriTabAdrCmd
bl controlLoad
1:
ldr r0,iAdrszMessInput @ display input message
bl affichageMess
mov r0,#STDIN @ Linux input console
ldr r1,iAdrsBuffer @ buffer address
mov r2,#BUFFERSIZE @ buffer size
mov r7, #READ @ request to read datas
svc 0 @ call system
sub r0,r0,#1
mov r2,#0
strb r2,[r1,r0] @ replace character 0xA by zéro final
ldr r0,iAdrsBuffer
ldr r1,iAdriTabAdrCmd
bl controlCommand @ control text command
mov r2,r0
bl affichageMess
ldr r0,iAdrszCarriageReturn
bl affichageMess
mov r0,r2
ldr r1,iAdrszCmdQuit @ command quit ?
bl comparStrings
cmp r0,#0
beq 100f @ yes -> end
b 1b @ else loop
99:
ldr r0,iAdrszMessErrBuffer
bl affichageMess
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
iAdrszMessErrBuffer: .int szMessErrBuffer
iAdrsZoneConv: .int sZoneConv
iAdrszMessInput: .int szMessInput
iAdrszCmdQuit: .int szCmdQuit
/******************************************************************/
/* control abbrevation command */
/******************************************************************/
/* r0 contains string input command */
/* r1 contains address table string command */
controlCommand: @ INFO: controlCommand
push {r1-r8,lr} @ save registers
mov r8,r0
mov r9,r1
bl computeLength @ length input command
mov r4,r0 @ save length input
mov r2,#0 @ indice
mov r3,#0 @ find counter
1:
mov r0,r8
ldr r1,[r9,r2,lsl #2] @ load a item
cmp r1,#0 @ end ?
beq 5f
bl comparStringSpe @
cmp r0,#0 @ no found other search
beq 4f
mov r6,#0
mov r5,#0
2: @ loop count capital letters
ldrb r0,[r1,r6]
cmp r0,#0
beq 3f
tst r0,#0x20 @ capital letter ?
addeq r5,r5,#1
add r6,r6,#1
b 2b
3:
cmp r4,r5 @ input < command capital letters
blt 4f @ no correct
add r3,r3,#1 @ else increment counter
mov r7,r1 @ and save address command
4:
add r2,r2,#1 @ increment indice
b 1b @ and loop
5:
cmp r3,#1 @ no find or multiple find ?
bne 99f @ error
@ one find
mov r0,r7 @ length command table
bl computeLength
cmp r4,r0 @ length input > command ?
bgt 99f @ error
mov r4,#0x20 @ 5 bit to 1
mov r2,#0
6:
ldrb r3,[r7,r2]
cmp r3,#0
beq 7f
bic r3,r3,r4 @ convert to capital letter
strb r3,[r8,r2]
add r2,r2,#1
b 6b
7:
strb r3,[r8,r2]
mov r0,r8 @ return string input address
b 100f
99:
ldr r0,iAdrszMessErrorAbr @ return string "error"
100:
pop {r1-r8,lr} @ restaur registers
bx lr @return
iAdrszMessErreur: .int szMessErreur
iAdrszMessErrorAbr: .int szMessErrorAbr
/******************************************************************/
/* comparaison first letters String */
/******************************************************************/
/* r0 contains first String */
/* r1 contains second string */
/* r0 return 0 if not find else returns number letters OK */
comparStringSpe:
push {r1-r6,lr} @ save register
mov r2,#0
1:
ldrb r3,[r0,r2] @ input
orr r4,r3,#0x20 @ convert capital letter
ldrb r5,[r1,r2] @ table
orr r6,r5,#0x20 @ convert capital letter
cmp r4,r6
bne 2f
cmp r3,#0
beq 3f
add r2,r2,#1
b 1b
2:
cmp r3,#0 @ fist letters Ok
beq 3f
mov r0,#0 @ no ok
b 100f
3:
mov r0,r2
100:
pop {r1-r6,lr} @ restaur registers
bx lr @return
/******************************************************************/
/* compute length String */
/******************************************************************/
/* r0 contains String */
/* r0 return length */
computeLength: @ INFO: functionFN
push {r1-r2,lr} @ save register
mov r1,#0
1:
ldrb r2,[r0,r1]
cmp r2,#0 @ end ?
moveq r0,r1 @ return length in r0
beq 100f
add r1,r1,#1
b 1b
100:
pop {r1-r2,lr} @ restaur registers
bx lr @return
/******************************************************************/
/* read file */
/******************************************************************/
/* r0 contains address stack begin */
traitFic: @ INFO: traitFic
push {r1-r8,fp,lr} @ save registers
mov fp,r0 @ fp <- start address
ldr r4,[fp] @ number of Command line arguments
cmp r4,#1
movle r0,#-1
ble 99f
add r5,fp,#8 @ second parameter address
ldr r5,[r5]
ldr r0,iAdriAdrFicName
str r5,[r0]
ldr r0,iAdrszMessTitre
bl affichageMess @ display string
mov r0,r5
bl affichageMess
ldr r0,iAdrszCarriageReturn
bl affichageMess @ display carriage return
mov r0,r5 @ file name
mov r1,#O_RDWR @ flags
mov r2,#0 @ mode
mov r7, #OPEN @ call system OPEN
svc 0
cmp r0,#0 @ error ?
ble 99f
mov r8,r0 @ File Descriptor
ldr r1,iAdrsBufferCmd @ buffer address
mov r2,#BUFFERSIZE @ buffer size
mov r7,#READ @ read file
svc #0
cmp r0,#0 @ error ?
blt 99f
@ extraction datas
ldr r1,iAdrsBufferCmd @ buffer address
add r1,r0
mov r0,#0 @ store zéro final
strb r0,[r1]
ldr r0,iAdriTabAdrCmd @ key string command table
ldr r1,iAdrsBufferCmd @ buffer address
bl extracDatas
@ close file
mov r0,r8
mov r7, #CLOSE
svc 0
mov r0,#0
b 100f
99: @ error
ldr r1,iAdrszMessErreur @ error message
bl displayError
mov r0,#-1
100:
pop {r1-r8,fp,lr} @ restaur registers
bx lr @return
iAdriAdrFicName: .int iAdrFicName
iAdrszMessTitre: .int szMessTitre
iAdrsBuffer: .int sBuffer
iAdrsBufferCmd: .int sBufferCmd
iAdriTabAdrCmd: .int iTabAdrCmd
/******************************************************************/
/* extrac digit file buffer */
/******************************************************************/
/* r0 contains strings address */
/* r1 contains buffer address */
extracDatas: @ INFO: extracDatas
push {r1-r8,lr} @ save registers
mov r7,r0
mov r6,r1
mov r2,#0 @ string buffer indice
mov r4,r1 @ start string
mov r5,#0 @ string index
//vidregtit debextrac
1:
ldrb r3,[r6,r2]
cmp r3,#0
beq 4f @ end
cmp r3,#0xA
beq 2f
cmp r3,#' ' @ end string
beq 3f
add r2,#1
b 1b
2:
mov r3,#0
strb r3,[r6,r2]
ldrb r3,[r6,r2]
cmp r3,#0xD
addeq r2,#2
addne r2,#1
b 4f
3:
mov r3,#0
strb r3,[r6,r2]
add r2,#1
4:
mov r0,r4
str r4,[r7,r5,lsl #2]
add r5,#1
5:
ldrb r3,[r6,r2]
cmp r3,#0
beq 100f
cmp r3,#' '
addeq r2,r2,#1
beq 5b
add r4,r6,r2 @ new start address
b 1b
100:
pop {r1-r8,lr} @ restaur registers
bx lr @return
/******************************************************************/
/* control load */
/******************************************************************/
/* r0 contains string table */
controlLoad:
push {r1-r8,lr} @ save registers
mov r5,r0
mov r1,#0
1:
ldr r0,[r5,r1,lsl #2]
cmp r0,#0
beq 100f
bl affichageMess
ldr r0,iAdrszCarriageReturn
bl affichageMess
add r1,r1,#1
b 1b
100:
pop {r1-r8,lr} @ restaur registers
bx lr @return
/************************************/
/* 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 @ equal
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"