Hey guys what I'm trying to do is to sum two arrays and return a new array; for example if given
uint8_t a[] = {2, 4, 6};
uint8_t b[] = {1, 2, 3};
I should get { 3, 6, 9}
What I'm trying to do is have a .ino file call on an assembly file that will do this in assembly and not in C and this is what I currently have in assembly:
// mimics void sumArrays(uint8_t *a, uint8_t *b, uint8_t *c, byte length){} method
.global sumArrays
sumArrays:
//r18 is the byte length
//r24 and r25 first array 31,30
//r23 and r22 second array 29,28
//r21 and r20 third array 27,26
mov r30, r24
mov r31, r25
mov r28, r22
mov r29, r23
mov r26, r20
mov r27, r21
ldi r17, 0 //counter variable
ldi r19, 1
call printRegs
//jmp sumLoop
ret
sumLoop:
cp r17, r18
brge endSumLoop
ldi r16, 0
add r16, Z+
add r16, Y+
st X+, r16
add r17, r23
jmp sumLoop:
endSumLoop:
ret
However, I get sketch/assignment13.S:65: Error: constant value required
which is most likely from the
add r16, Z+
add r16, Y+
Lines but otherwise, how would I add it to a temporary variable while progressing the pointer?
-
2Why are you using assembly for this instead of C?Gabriel Staples– Gabriel Staples2020年12月12日 05:19:09 +00:00Commented Dec 12, 2020 at 5:19
1 Answer 1
add r16, Z+
You probably meant something like
add r16, memory[Z+]
However, the AVR is a RISC processor. It has instructions to address the memory, and instructions to do arithmetics, but it has no "complex" instructions that both address the memory and do arithmetics with the addressed data. So you have to use separate instructions to:
Load (
ld
) the data from RAMdo the arithmetics
store (
st
) the result in RAM
Now, looking at your assemble code, I have a few comments:
If you are mixing assembly and C/C++, you should pay attention to the ABI conventions. Specifically, some registers, like r28 and r29, "belong" to the caller. If your function needs to use them, it should save their contents (typically by
push
ing them to the stack) before clobbering them, and restore them (pop
) before returning.For adding two 8-bit numbers (a + b), a single addition is enough. There is no point in starting the addition with zero (i.e. computing 0 + a + b).
For managing the counter, it can be more convenient to decrement the initial count you where given (like in C:
if (--length) return;
) rather than using an extra variable that is incremented.There is no need to split such a simple function into smaller functions.
Explore related questions
See similar questions with these tags.