Getting serial garbage when using registers 24-30 for mul - inline assembly

For an assignment I am working on a matrix multiplication where we need to code it using inline assembly. I am a newbie in AVR assembly.

For some reason, when i use registers 24-30 as operands of 'muls' or 'mul' instruction, the Serial starts giving garbage.

#include <stdint.h>

#define DEBUG

volatile int8_t mat_a[4] = {28, 122, 80, 42};//, 54, 122, 98, 42, 99, 58, 124, 29, 21};
volatile int8_t mat_b[4] = {102, 106, 65, 114};//, 25, 45, 39, 58, 119, 121, 29, 70, 123};

volatile uint32_t mat_c = 0;


void setup(){
    Serial.begin(9600);
}

void loop(){

    asm(

        "lds r16, (mat_a+0) \n"
        "lds r17, (mat_a+1) \n"
        "lds r18, (mat_a+2) \n"
        "lds r19, (mat_a+3) \n"

        "lds r24, (mat_b+0) \n"
        "lds r25, (mat_b+1) \n"
        "lds r26, (mat_b+2) \n"
        "lds r27, (mat_b+3) \n"
    );

    asm(
        // ------- gives garbage ------
        "muls r16, r24 \n"
        // "muls r16, r25 \n"
        // "muls r16, r26 \n"
        // "muls r16, r27 \n"
        // "muls r16, r28 \n"
        // "muls r16, r29 \n"
        // "muls r16, r30 \n"

        // ------- works fine ------
        // "muls r16, r23 \n"
        // "muls r16, r31 \n"
    );

    asm(
        // // store to result
        "sts (mat_c + 0), r16 \n"
        "sts (mat_c + 1), r17 \n"
        "sts (mat_c + 2), r18 \n"
        "sts (mat_c + 3), r19 \n"
    );

    #ifdef DEBUG
        Serial.print("value: ");
        Serial.println(mat_c);
    #endif

}

(Please note the above code is just a work-in-progress. To demonstrate the point.)

How can i avoid this? Because its really limiting the number of registers i can use. (7 out of 16)

I'd code that in C, then study the register usage in the compiled code. Eventually register variables can make the code work.

Also see how higher registers are used for stack and pointer arithmetic. Which controller do you use? Why don't you use the lower registers?

DrDiettrich:
I'd code that in C, then study the register usage in the compiled code. Eventually register variables can make the code work.
Also see how higher registers are used for stack and pointer arithmetic. Why don't you use the lower registers?

Yes that's a good idea. I will try to check the compiled assembly. Thank you!

Well the specification only allows registers 16-31 for multiplication instructions.