Created
May 27, 2012 01:35
-
-
Save lukecameron/2795833 to your computer and use it in GitHub Desktop.
a string length function in AVR assembler
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* strlen.asm | |
* | |
* Created: 28/03/2012 6:00:53 PM | |
* Author: Luke | |
*/ | |
/* | |
* strlen.asm | |
* | |
* Created: 28/03/2012 4:24:50 PM | |
* Author: Luke | |
*/ | |
; A strlen function | |
.include "m64def.inc" | |
.def zero = r16 | |
.cseg | |
jmp main | |
shortString:.db "hello" | |
longString:.db "supsupsupsupsupsupsupsupsupsupsup sup sup sup sup sup sups" | |
main: | |
;init the stack (main has no stack frame as it doesn't store anything) | |
ldi YL, low(RAMEND) | |
ldi YH, high(RAMEND) | |
out SPH, YH | |
out SPL, YL | |
;create our zero constant | |
ldi zero, 0 ;hehehe | |
;strlen uses r21:r20 as its input parameter (arbitrarily chosen) | |
;remember that the return value will be in r25:r24 | |
;calculate the length of shortString (should be five) | |
ldi r21, low(shortString) | |
ldi r20, high(shortString) | |
rcall strlenn | |
end: | |
rjmp end | |
strlenn: | |
;some variable names | |
.def count = r2 | |
.def char = r3 | |
;prologue | |
;push conflict registers | |
push ZH ;we use Z as our current pointer into program memory | |
push ZL | |
push YL | |
push YH | |
push char ;could have made this a local, but didn't bother since it's temp | |
;reserve space for locals and parems | |
;locals: int8 count. parems: char *str. = three bytes | |
;I might make count an int16 at some stage | |
sbiw Y, 3 ;subtracts 3 from Y | |
out SPH, YH | |
out SPL, YL | |
;store parameter on the stack | |
std Y+1, r20 | |
std Y+2, r21 | |
;store count on the stack | |
std Y+3, zero | |
;body | |
ldd count, Y+3 ;load our count from the stack into r2 | |
ldd ZH, Y+1 ;load our string pointer from the stack | |
ldd ZL, Y+2 | |
;a post-check loop | |
loop: | |
;load the next char from flash | |
lpm char, Z+ ;increment Z as well since we always want to load the next char | |
cp char, zero | |
breq loopend | |
inc count | |
rjmp loop | |
loopend: | |
;epilogue | |
;store the result in r25:r24 | |
mov r25, count | |
;deallocate locals and params | |
adiw Y, 3 | |
out SPH, YH | |
out SPL, YL | |
;restore conflict registers | |
pop char | |
pop YH | |
pop YL | |
pop ZL | |
pop ZH | |
ret |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This is very helpful. Thank you for this.