1

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?

jsotola
1,5342 gold badges12 silver badges20 bronze badges
asked Dec 12, 2020 at 2:20
1
  • 2
    Why are you using assembly for this instead of C? Commented Dec 12, 2020 at 5:19

1 Answer 1

2
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:

  1. Load (ld) the data from RAM

  2. do the arithmetics

  3. store (st) the result in RAM

Now, looking at your assemble code, I have a few comments:

  1. 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 pushing them to the stack) before clobbering them, and restore them (pop) before returning.

  2. 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).

  3. 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.

  4. There is no need to split such a simple function into smaller functions.

answered Dec 12, 2020 at 12:58

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.