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?

1
  • 2
    Why are you using assembly for this instead of C? Dec 12 '20 at 5:19
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.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.