|
corrected, tested, and commented version of the above example code @ hashsz s = {
@ h := 53u
@ itersz s, b => {
@ h = (h >> 27 | h << 5) ^ b
@ }
@ return h
@ }
.syntax unified
.thumb
itersz: push {r6, r7, r8, lr} @ r6 and r7 are preserved by blocks
mov r7, r0 @ so put the string pointer in r7
mov r6, r1 @ and the block code pointer in r6
1: ldrb r0, [r7], #1 @ loop over string bytes, post-indexing
cbz r0, 1f @ bail out on NUL, but otherwise
blx r1 @ invoke block argument with byte, then
b 1b @ repeat loop
1: pop {r6, r7, r8, pc} @ restore registers and return
hashsz: push {r4, lr} @ r4 is callee-preserved and passed to blocks
movs r4, #53 @ initial value of hash
adr r1, 1f+1 @ load Thumbified pointer for block using gas local label
bl itersz @ invoke iterator subroutine
mov r0, r4 @ load completed hash into return value
pop {r4, pc} @ restore and return
1: eor r4, r0, r4, ror #27 @ block argument rotates & xors the byte in r0
bx lr @ then resumes the iterator
|
years ago, in fact