avr-gcc: Itearting over char array does not work with too many iterations

Viewed 121

I have an simple function that iterates over an character array and calls a function with each character.

void loopFunction(void)                                                                                                                                               
{
    char *mystring = "ABCDEF";
    int i = 0;
    for (i = 0; i<3; i++) {
        LCD_Write(mystring[i]);
    }
}

This function works fine, deliviering the proper output (in the end on my LCD display), and the intermediate assembler code looks fine:

loopFunction:
/* prologue: function */
/* frame size = 0 */
/* stack size = 0 */
.L__stack_usage = 0 
    ldi r24,lo8(65)
    call LCD_Write
    ldi r24,lo8(66)
    call LCD_Write
    ldi r24,lo8(67)
    jmp LCD_Write
    .size   loopFunction, .-loopFunction  

As we can see, the loop has converted to simply calling the function three times.

Now, the problem begins when i want to execute the loop 4 times:

void loopFunction(void)                                                                                                                                               
{
    char *mystring = "ABCDEF";
    int i = 0;
    for (i = 0; i<4; i++) {
        LCD_Write(mystring[i]);
    }
}


loopFunction:
    push r28
    push r29
/* prologue: function */
/* frame size = 0 */
/* stack size = 2 */
.L__stack_usage = 2
    ldi r28,lo8(.LC0)
    ldi r29,hi8(.LC0)
.L12:
    ld r24,Y+
    call LCD_Write
    ldi r24,hi8(.LC0+4)
    cpi r28,lo8(.LC0+4)
    cpc r29,r24
    brne .L12
/* epilogue start */                                                                                                                                                      
    pop r29
    pop r28
    ret

So, to me it seems that the actually stored string is never accessed

.LC0:
    .string "ABCDEF"
    .text

What I am duing wrong?

I am calling avr-gcc

avr-gcc -mmcu=atmega16 -Wall -O3 --save-temps -Os -c lcd.c

on a Debian10 with packages from buster repo

  • avr-gcc version 5.4.0
  • avr-libc 2.0.0+Atmel3.6.1-2
1 Answers

The stored string is accessed in the part of the assembly code that says Y+.

That fragment of code means to read from the Y pointer and then increment the pointer. The Y pointer is stored in registers r29 and r28. The first two ldi instructions in your assembly set the Y pointer to point at the beginning of the stored string.

Related