54 lines
1.7 KiB
Text
54 lines
1.7 KiB
Text
@ Check whether the ASCII string in [r0] is a palindrome
|
|
@ Returns with zero flag set if palindrome.
|
|
palin: mov r1,r0 @ Find end of string
|
|
1: ldrb r2,[r1],#1 @ Grab character and increment pointer
|
|
tst r2,r2 @ Zero yet?
|
|
bne 1b @ If not try next byte
|
|
sub r1,r1,#2 @ Move R1 to last actual character.
|
|
2: cmp r0,r1 @ When R0 >= R1,
|
|
cmpgt r2,r2 @ make sure zero is set,
|
|
bxeq lr @ and stop (the string is a palindrome).
|
|
ldrb r2,[r1],#-1 @ Grab [R1] (end) and decrement.
|
|
ldrb r3,[r0],#1 @ Grab [R0] (begin) and increment
|
|
cmp r2,r3 @ Are they equal?
|
|
bxne lr @ If not, it's not a palindrome.
|
|
b 2b @ Otherwise, try next pair.
|
|
|
|
@ Try the function on a couple of strings
|
|
.global _start
|
|
_start: ldr r8,=words @ Word pointer
|
|
1: ldr r9,[r8],#4 @ Grab word and move pointer
|
|
tst r9,r9 @ Null?
|
|
moveq r7,#1 @ Then we're done; syscall 1 = exit
|
|
swieq #0
|
|
mov r1,r9 @ Print the word
|
|
bl print
|
|
mov r0,r9 @ Test if the word is a palindrome
|
|
bl palin
|
|
ldreq r1,=yes @ "Yes" if it is a palindrome
|
|
ldrne r1,=no @ "No" if it's not a palindrome
|
|
bl print
|
|
b 1b @ Next word
|
|
|
|
@ Print zero-terminated string [r1] using Linux syscall
|
|
print: push {r7,lr} @ Keep R7 and link register
|
|
mov r2,r1 @ Find end of string
|
|
1: ldrb r0,[r2],#1 @ Grab character and increment pointer
|
|
tst r0,r0 @ Zero yet?
|
|
bne 1b @ If not, keep going
|
|
sub r2,r2,r1 @ Calculate length of string (bytes to write)
|
|
mov r0,#1 @ Stdout = 1
|
|
mov r7,#4 @ Syscall 4 = write
|
|
swi #0 @ Make the syscall
|
|
pop {r7,lr} @ Restore R7 and link register
|
|
bx lr
|
|
|
|
@ Strings
|
|
yes: .asciz ": yes\n" @ Output yes or no
|
|
no: .asciz ": no\n"
|
|
w1: .asciz "rotor" @ Words to test
|
|
w2: .asciz "racecar"
|
|
w3: .asciz "level"
|
|
w4: .asciz "redder"
|
|
w5: .asciz "rosetta"
|
|
words: .word w1,w2,w3,w4,w5,0
|