RosettaCodeData/Task/Substring/ARM-Assembly/substring.arm

309 lines
12 KiB
Plaintext

/* ARM assembly Raspberry PI */
/* program substring.s */
/* Constantes */
.equ STDOUT, 1 @ Linux output console
.equ EXIT, 1 @ Linux syscall
.equ WRITE, 4 @ Linux syscall
.equ BUFFERSIZE, 100
/* Initialized data */
.data
szMessString: .asciz "Result : "
szString1: .asciz "abcdefghijklmnopqrstuvwxyz"
szStringStart: .asciz "abcdefg"
szCarriageReturn: .asciz "\n"
/* UnInitialized data */
.bss
szSubString: .skip 500 @ buffer result
/* code section */
.text
.global main
main:
ldr r0,iAdrszString1 @ address input string
ldr r1,iAdrszSubString @ address output string
mov r2,#22 @ location
mov r3,#4 @ length
bl subStringNbChar @ starting from n characters in and of m length
ldr r0,iAdrszMessString @ display message
bl affichageMess
ldr r0,iAdrszSubString @ display substring result
bl affichageMess
ldr r0,iAdrszCarriageReturn @ display line return
bl affichageMess
@
ldr r0,iAdrszString1
ldr r1,iAdrszSubString
mov r2,#15 @ location
bl subStringEnd @starting from n characters in, up to the end of the string
ldr r0,iAdrszMessString @ display message
bl affichageMess
ldr r0,iAdrszSubString
bl affichageMess
ldr r0,iAdrszCarriageReturn @ display line return
bl affichageMess
@
ldr r0,iAdrszString1
ldr r1,iAdrszSubString
bl subStringMinus @ whole string minus last character
ldr r0,iAdrszMessString @ display message
bl affichageMess
ldr r0,iAdrszSubString
bl affichageMess
ldr r0,iAdrszCarriageReturn @ display line return
bl affichageMess
@
ldr r0,iAdrszString1
ldr r1,iAdrszSubString
mov r2,#'c' @ start character
mov r3,#5 @ length
bl subStringStChar @starting from a known character within the string and of m length
cmp r0,#-1 @ error ?
beq 2f
ldr r0,iAdrszMessString @ display message
bl affichageMess
ldr r0,iAdrszSubString
bl affichageMess
ldr r0,iAdrszCarriageReturn @ display line return
bl affichageMess
@
2:
ldr r0,iAdrszString1
ldr r1,iAdrszSubString
ldr r2,iAdrszStringStart @ sub string to start
mov r3,#10 @ length
bl subStringStString @ starting from a known substring within the string and of m length
cmp r0,#-1 @ error ?
beq 3f
ldr r0,iAdrszMessString @ display message
bl affichageMess
ldr r0,iAdrszSubString
bl affichageMess
ldr r0,iAdrszCarriageReturn @ display line return
bl affichageMess
3:
100: @ standard end of the program
mov r0, #0 @ return code
mov r7, #EXIT @ request to exit program
svc 0 @ perform system call
iAdrszMessString: .int szMessString
iAdrszString1: .int szString1
iAdrszSubString: .int szSubString
iAdrszStringStart: .int szStringStart
iAdrszCarriageReturn: .int szCarriageReturn
/******************************************************************/
/* sub strings index start number of characters */
/******************************************************************/
/* r0 contains the address of the input string */
/* r1 contains the address of the output string */
/* r2 contains the start index */
/* r3 contains numbers of characters to extract */
/* r0 returns number of characters or -1 if error */
subStringNbChar:
push {r1-r5,lr} @ save registers
mov r4,#0 @ counter byte output string
1:
ldrb r5,[r0,r2] @ load byte string input
cmp r5,#0 @ zero final ?
beq 2f
strb r5,[r1,r4] @ store byte output string
add r2,#1 @ increment counter
add r4,#1
cmp r4,r3 @ end ?
blt 1b @ no -> loop
2:
mov r5,#0
strb r5,[r1,r4] @ load byte string 2
mov r0,r4
100:
pop {r1-r5,lr} @ restaur registers
bx lr @ return
/******************************************************************/
/* sub strings index start at end of string */
/******************************************************************/
/* r0 contains the address of the input string */
/* r1 contains the address of the output string */
/* r2 contains the start index */
/* r0 returns number of characters or -1 if error */
subStringEnd:
push {r1-r5,lr} @ save registers
mov r4,#0 @ counter byte output string
1:
ldrb r5,[r0,r2] @ load byte string 1
cmp r5,#0 @ zero final ?
beq 2f
strb r5,[r1,r4]
add r2,#1
add r4,#1
b 1b @ loop
2:
mov r5,#0
strb r5,[r1,r4] @ load byte string 2
mov r0,r4
100:
pop {r1-r5,lr} @ restaur registers
bx lr
/******************************************************************/
/* whole string minus last character */
/******************************************************************/
/* r0 contains the address of the input string */
/* r1 contains the address of the output string */
/* r0 returns number of characters or -1 if error */
subStringMinus:
push {r1-r5,lr} @ save registers
mov r2,#0 @ counter byte input string
mov r4,#0 @ counter byte output string
1:
ldrb r5,[r0,r2] @ load byte string
cmp r5,#0 @ zero final ?
beq 2f
strb r5,[r1,r4]
add r2,#1
add r4,#1
b 1b @ loop
2:
sub r4,#1
mov r5,#0
strb r5,[r1,r4] @ load byte string 2
mov r0,r4
100:
pop {r1-r5,lr} @ restaur registers
bx lr
/******************************************************************/
/* starting from a known character within the string and of m length */
/******************************************************************/
/* r0 contains the address of the input string */
/* r1 contains the address of the output string */
/* r2 contains the character */
/* r3 contains the length
/* r0 returns number of characters or -1 if error */
subStringStChar:
push {r1-r5,lr} @ save registers
mov r6,#0 @ counter byte input string
mov r4,#0 @ counter byte output string
1:
ldrb r5,[r0,r6] @ load byte string
cmp r5,#0 @ zero final ?
streqb r5,[r1,r4]
moveq r0,#-1
beq 100f
cmp r5,r2
beq 2f
add r6,#1
b 1b @ loop
2:
strb r5,[r1,r4]
add r6,#1
add r4,#1
cmp r4,r3
bge 3f
ldrb r5,[r0,r6] @ load byte string
cmp r5,#0
bne 2b
3:
mov r5,#0
strb r5,[r1,r4] @ load byte string 2
mov r0,r4
100:
pop {r1-r5,lr} @ restaur registers
bx lr
/******************************************************************/
/* starting from a known substring within the string and of m length */
/******************************************************************/
/* r0 contains the address of the input string */
/* r1 contains the address of the output string */
/* r2 contains the address of string to start */
/* r3 contains the length
/* r0 returns number of characters or -1 if error */
subStringStString:
push {r1-r8,lr} @ save registers
mov r7,r0 @ save address
mov r8,r1 @ counter byte string
mov r1,r2
bl searchSubString
cmp r0,#-1
beq 100f
mov r6,r0 @ counter byte input string
mov r4,#0
1:
ldrb r5,[r7,r6] @ load byte string
strb r5,[r8,r4]
cmp r5,#0 @ zero final ?
moveq r0,r4
beq 100f
add r4,#1
cmp r4,r3
addlt r6,#1
blt 1b @ loop
mov r5,#0
strb r5,[r8,r4]
mov r0,r4
100:
pop {r1-r8,lr} @ restaur registers
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
/******************************************************************/
/* display text with size calculation */
/******************************************************************/
/* r0 contains the address of the message */
affichageMess:
push {r0,r1,r2,r7,lr} @ save registers
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"
svc #0 @ call system
pop {r0,r1,r2,r7,lr} @ restaur registers
bx lr @ return