реклама на сайте
подробности

 
 
> Указатель во флэш и IAR
Makki
сообщение Dec 25 2011, 19:06
Сообщение #1


Участник
*

Группа: Участник
Сообщений: 19
Регистрация: 8-10-07
Пользователь №: 31 163



Доброго всем времени суток!
С недавних пор начал разбираться с компилятором IAR, до этого писал на ассемблере. Начал простенький проектик с графическим дисплеем. Пытаюсь вывести на экран строку, расположенную в памяти программ. Строка, конечно, выводится, отображается как надо, но вот какими методами...
В общем, есть у меня функция:
Код
void lcd_write_string(char __flash * string)
{
  char i= * string++;
  while(i--!=0)
  {
    lcd_write_character(*string++);
  }
}


Принимает она указатель на flash, где переменная где у меня выглядит следующим образом:
char __flash string[]={5,'A','B','C','D','E'};
5 - число символов в строке, дальше символы.

При компиляции всего этого начинаются для меня непонятные вещи:
Код
@00000057: lcd_write_string
46:       void lcd_write_string(char __flash * string)
47:       {
+00000057:   940E00D2    CALL      0x000000D2     Call subroutine;тут компилятор сохраняет в программный стек регистры, хотя это и не нужно, ну да ладно
+00000059:   01C8        MOVW      R24,R16        Copy register pair;тут получили указатель, переданный через пару регистров R16:R17
48:         char i= * string++;
+0000005A:   01FC        MOVW      R30,R24        Copy register pair;но почему было сразу их не занести в ZH:ZL???
+0000005B:   91A4        LPM       R26,Z          Load program memory;если бы сразу занесли в ZH:ZL, можно бы было сделать LPM R26,Z+
+0000005C:   9601        ADIW      R24,0x01       Add immediate to word;тогда эта строка лишняя
+0000005D:   C004        RJMP      PC+0x0005      Relative jump;прыг +5
51:           lcd_write_character(*string++);
+0000005E:   01FC        MOVW      R30,R24        Copy register pair;опять переносим в Z указатель
+0000005F:   9104        LPM       R16,Z          Load program memory
+00000060:   DFE9        RCALL     PC-0x0016      Relative call subroutine;собственно, запись символа
+00000061:   9601        ADIW      R24,0x01       Add immediate to word;и почему-то увеличиваем указатель уже после выполнения функции
49:         while(i--!=0)
+00000062:   2F0A        MOV       R16,R26        Copy register;вот зачем дальше вся эта чехарда, когда можно просто проверить R26???
+00000063:   2FA0        MOV       R26,R16        Copy register
+00000064:   95AA        DEC       R26            Decrement
+00000065:   2300        TST       R16            Test for Zero or Minus
+00000066:   F7B9        BRNE      PC-0x08        Branch if not equal;прыг на -8
53:       }
+00000067:   E0E3        LDI       R30,0x03       Load immediate
+00000068:   940C00D6    JMP       0x000000D6     Jump


Итак, вопрос: это такая работа компилятора, или это я чего-то не знаю? Как напрямую в регистр ZH:ZL скормить указатель и работать именно с этими регистрами? Нет, я могу то же самое написать на ассемблере, и ассемблерную библиотеку прикрутить, но зачем тогда мне компилятор?
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
Chameleon
сообщение Dec 25 2011, 21:19
Сообщение #2


Участник
*

Группа: Участник
Сообщений: 50
Регистрация: 5-07-08
Пользователь №: 38 757



Оптимизацию включать не пробовали?

Вы как-то странно строки инициализируете. Вы каждый раз вручную будете вычислять длину строки?

Почему нельзя записать

char __flash string[]="ABCDE";

И потом проверять ноль в конце строки? Ноль сам компилятор добавит.

Сообщение отредактировал Chameleon - Dec 25 2011, 21:29
Go to the top of the page
 
+Quote Post
Makki
сообщение Dec 26 2011, 07:04
Сообщение #3


Участник
*

Группа: Участник
Сообщений: 19
Регистрация: 8-10-07
Пользователь №: 31 163



Цитата(Chameleon @ Dec 26 2011, 00:19) *
Оптимизацию включать не пробовали?
Вы как-то странно строки инициализируете. Вы каждый раз вручную будете вычислять длину строки?
Почему нельзя записать
char __flash string[]="ABCDE";
И потом проверять ноль в конце строки? Ноль сам компилятор добавит.

Полная оптимизация по скорости добавила таки команду LPM R16,Z+, счетчик теперь хранится только в R26, но хранение указателя в регистрах R25:R24 осталось. Наверное, есть какой-нибудь способ, чтобы жестко привязаться к регистрам ZH:ZL, если это все же предусмотрено компилятором. Будем искать...
Код
@00000054: lcd_write_string
46:       void lcd_write_string(char __flash * string)
47:       {
+00000054:   93AA        ST        -Y,R26         Store indirect and predecrement
+00000055:   939A        ST        -Y,R25         Store indirect and predecrement
+00000056:   938A        ST        -Y,R24         Store indirect and predecrement
48:         char i= * string++;
+00000057:   01F8        MOVW      R30,R16        Copy register pair
+00000058:   91A5        LPM       R26,Z+         Load program memory and postincrement
+00000059:   01CF        MOVW      R24,R30        Copy register pair
+0000005A:   23AA        TST       R26            Test for Zero or Minus
+0000005B:   F039        BREQ      PC+0x08        Branch if equal
+0000005C:   95AA        DEC       R26            Decrement
51:           lcd_write_character(*string++);
+0000005D:   01FC        MOVW      R30,R24        Copy register pair
+0000005E:   9105        LPM       R16,Z+         Load program memory and postincrement
+0000005F:   01CF        MOVW      R24,R30        Copy register pair
+00000060:   DFE7        RCALL     PC-0x0018      Relative call subroutine
+00000061:   23AA        TST       R26            Test for Zero or Minus
+00000062:   F7C9        BRNE      PC-0x06        Branch if not equal
53:       }
+00000063:   9189        LD        R24,Y+         Load indirect and postincrement
+00000064:   9199        LD        R25,Y+         Load indirect and postincrement
+00000065:   91A9        LD        R26,Y+         Load indirect and postincrement
+00000066:   9508        RET                      Subroutine return

А по поводу хранения строки - это у меня после написания протокола modbus привычка осталась - значение, например, порта ввода-вывода любым может быть, и конец посылки по символу определять некорректно.
Go to the top of the page
 
+Quote Post



Reply to this topicStart new topic
2 чел. читают эту тему (гостей: 2, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 21st August 2025 - 15:16
Рейтинг@Mail.ru


Страница сгенерированна за 0.01389 секунд с 7
ELECTRONIX ©2004-2016