avr-g cc: Итерация по массиву char не работает с большим количеством итераций - PullRequest
1 голос
/ 23 марта 2020

У меня есть простая функция, которая перебирает массив символов и вызывает функцию с каждым символом.

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

Эта функция работает нормально, обеспечивая правильный вывод (в конце концов на моем ЖК-дисплее), и код промежуточного ассемблера выглядит хорошо:

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  

Как мы видим, l oop преобразуется в простой вызов функции три раза.

Теперь проблема начинается, когда я хочу выполнить l oop 4 раза:

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

Итак, мне кажется, что к фактически сохраненной строке никогда не обращаются

.LC0:
    .string "ABCDEF"
    .text

Что я неправильно понял?

Я звоню avr-g cc

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

на Debian10 с пакетами из репозитория Buster Repo

  • avr-g cc версия 5.4.0
  • avr-lib c 2.0.0 + Atmel3.6.1-2

1 Ответ

2 голосов
/ 24 марта 2020

Доступ к сохраненной строке осуществляется в той части кода сборки, которая гласит: Y+.

Этот фрагмент кода означает чтение из указателя Y, а затем увеличение указателя. Указатель Y хранится в регистрах r29 и r28. Первые две инструкции ldi в вашей сборке устанавливают указатель Y так, чтобы он указывал на начало сохраненной строки.

...