RosettaCodeData/Task/File-input-output/ARM-Assembly/file-input-output.arm

226 lines
7.3 KiB
Plaintext

/* ARM assembly Raspberry PI */
/* program readwrtfile.s */
/*********************************************/
/*constantes */
/********************************************/
.equ STDOUT, 1 @ Linux output console
.equ EXIT, 1 @ Linux syscall
.equ READ, 3
.equ WRITE, 4
.equ OPEN, 5
.equ CLOSE, 6
.equ CREATE, 8
/* file */
.equ O_RDWR, 0x0002 @ open for reading and writing
.equ TAILLEBUF, 1000
/*********************************/
/* Initialized data */
/*********************************/
.data
szMessErreur: .asciz "Erreur ouverture fichier input.\n"
szMessErreur4: .asciz "Erreur création fichier output.\n"
szMessErreur1: .asciz "Erreur fermeture fichier.\n"
szMessErreur2: .asciz "Erreur lecture fichier.\n"
szMessErreur3: .asciz "Erreur d'écriture dans fichier de sortie.\n"
szRetourligne: .asciz "\n"
szMessErr: .ascii "Error code : "
sDeci: .space 15,' '
.asciz "\n"
szNameFileInput: .asciz "input.txt"
szNameFileOutput: .asciz "output.txt"
/*******************************************/
/* DONNEES NON INITIALISEES */
/*******************************************/
.bss
sBuffer: .skip TAILLEBUF
/**********************************************/
/* -- Code section */
/**********************************************/
.text
.global main
main:
push {fp,lr} /* save registers */
ldr r0,iAdrszNameFileInput @ file name
mov r1,#O_RDWR @ flags
mov r2,#0 @ mode
mov r7,#OPEN @ call system OPEN
swi #0
cmp r0,#0 @ open error ?
ble erreur
mov r8,r0 @ save File Descriptor
ldr r1,iAdrsBuffer @ buffer address
mov r2,#TAILLEBUF @ buffer size
mov r7, #READ @ call system READ
swi 0
cmp r0,#0 @ read error ?
ble erreur2
mov r2,r0 @ length read characters
/* close imput file */
mov r0,r8 @ Fd
mov r7, #CLOSE @ call system CLOSE
swi 0
cmp r0,#0 @ close error ?
blt erreur1
@ create output file
ldr r0,iAdrszNameFileOutput @ file name
ldr r1,iFicMask1 @ flags
mov r7, #CREATE @ call system create file
swi 0
cmp r0,#0 @ create error ?
ble erreur4
mov r0,r8 @ file descriptor
ldr r1,iAdrsBuffer
@ et r2 contains the length to write
mov r7, #WRITE @ select system call 'write'
swi #0 @ perform the system call
cmp r0,#0 @ error write ?
blt erreur3
@ close output file
mov r0,r8 @ Fd fichier
mov r7, #CLOSE @ call system CLOSE
swi #0
cmp r0,#0 @ error close ?
blt erreur1
mov r0,#0 @ return code OK
b 100f
erreur:
ldr r1,iAdrszMessErreur
bl afficheerreur
mov r0,#1 @ error return code
b 100f
erreur1:
ldr r1,iAdrszMessErreur1
bl afficheerreur
mov r0,#1 @ error return code
b 100f
erreur2:
ldr r1,iAdrszMessErreur2
bl afficheerreur
mov r0,#1 @ error return code
b 100f
erreur3:
ldr r1,iAdrszMessErreur3
bl afficheerreur
mov r0,#1 @ error return code
b 100f
erreur4:
ldr r1,iAdrszMessErreur4
bl afficheerreur
mov r0,#1 @ error return code
b 100f
100: @ end program
pop {fp,lr} /* restaur des 2 registres */
mov r7, #EXIT /* appel fonction systeme pour terminer */
swi 0
iAdrszNameFileInput: .int szNameFileInput
iAdrszNameFileOutput: .int szNameFileOutput
iAdrszMessErreur: .int szMessErreur
iAdrszMessErreur1: .int szMessErreur1
iAdrszMessErreur2: .int szMessErreur2
iAdrszMessErreur3: .int szMessErreur3
iAdrszMessErreur4: .int szMessErreur4
iAdrsBuffer: .int sBuffer
iFicMask1: .octa 0644
/******************************************************************/
/* display text with size calculation */
/******************************************************************/
/* r0 contains the address of the message */
affichageMess:
push {r0,r1,r2,r7,lr} /* save registres */
mov r2,#0 /* counter length */
1: /* loop length calculation */
ldrb r1,[r0,r2] /* read octet start position + index */
cmp r1,#0 /* if 0 its over */
addne r2,r2,#1 /* else add 1 in the length */
bne 1b /* and loop */
/* so here r2 contains the length of the message */
mov r1,r0 /* address message in r1 */
mov r0,#STDOUT /* code to write to the standard output Linux */
mov r7, #WRITE /* code call system "write" */
swi #0 /* call systeme */
pop {r0,r1,r2,r7,lr} /* restaur des 2 registres */
bx lr /* return */
/***************************************************/
/* display error message */
/***************************************************/
/* r0 contains error code r1 address error message */
afficheerreur:
push {r1-r2,lr} @ save registers
mov r2,r0 @ save error code
mov r0,r1 @ address error message
bl affichageMess @ display error message
mov r0,r2 @ error code
ldr r1,iAdrsDeci @ result address
bl conversion10S
ldr r0,iAdrszMessErr @ display error code
bl affichageMess
pop {r1-r2,lr} @ restaur registers
bx lr @ return function
iAdrszMessErr: .int szMessErr
iAdrsDeci: .int sDeci
/***************************************************/
/* Converting a register to a signed decimal */
/***************************************************/
/* r0 contains value and r1 area address */
conversion10S:
push {r0-r4,lr} @ save registers
mov r2,r1 /* debut zone stockage */
mov r3,#'+' /* par defaut le signe est + */
cmp r0,#0 @ negative number ?
movlt r3,#'-' @ yes
mvnlt r0,r0 @ number inversion
addlt r0,#1
mov r4,#10 @ length area
1: @ start loop
bl divisionPar10R
add r1,#48 @ digit
strb r1,[r2,r4] @ store digit on area
sub r4,r4,#1 @ previous position
cmp r0,#0 @ stop if quotient = 0
bne 1b
strb r3,[r2,r4] @ store signe
subs r4,r4,#1 @ previous position
blt 100f @ if r4 < 0 -> end
mov r1,#' ' @ space
2:
strb r1,[r2,r4] @store byte space
subs r4,r4,#1 @ previous position
bge 2b @ loop if r4 > 0
100:
pop {r0-r4,lr} @ restaur registers
bx lr
/***************************************************/
/* division for 10 fast unsigned */
/***************************************************/
@ r0 contient le dividende
@ r0 retourne le quotient
@ r1 retourne le reste
divisionPar10R:
push {r2,lr} @ save registers
sub r1, r0, #10 @ calcul de r0 - 10
sub r0, r0, r0, lsr #2 @ calcul de r0 - (r0 /4)
add r0, r0, r0, lsr #4 @ calcul de (r0-(r0/4))+ ((r0-(r0/4))/16
add r0, r0, r0, lsr #8 @ etc ...
add r0, r0, r0, lsr #16
mov r0, r0, lsr #3
add r2, r0, r0, asl #2
subs r1, r1, r2, asl #1 @ calcul (N-10) - (N/10)*10
addpl r0, r0, #1 @ regul quotient
addmi r1, r1, #10 @ regul reste
pop {r2,lr}
bx lr