Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Странный asm код
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > Все остальные микроконтроллеры > MCS51
greatbaobab
Си знаю хорошо, а вот с кейлом только начинаю,
тем не менее это поставило меня в ступор.

простой код
Цитата
U8 i
for(i = 0; i < 255; i++);//задержка


который я бы "скомпилировал" бы так

Цитата
mov r0, 0xFF;
LOOP: djnz r0, LOOP;


компилируется в бесконечный цикл с непонятным колдовством в теле

Цитата
0B: CLR A;
0C: MOV R7, A;
0D: MOV A, R7; //СЮДА ЦИКЛ ПРЫГАТЬ БУДЕТ
0E: MOV R5, A;
0F: RLC A; //какие-то сдвиги
10: SUBB A, 0xE0; //какие-то непонятные константы
12: MOV R4, A;
13: CLR C;
14: MOV A, R5;
15: SUBB A, #0xFE; //какие-то вычитания
17: MOV A, R4;
18: XRL A, #P0 (0x80); // там был адрес указан, а не P0
1A: SUBB A, #P0 (0x80); // он что, ещё и с портом решил поработать зачем-то????
1C: JNC C:21; // я так понял выход из цикла, зачем???
1E: INC R7; //R7 я так понял, это счётчик i
1F: SJMP C:0D;//наверх //так и убрали бы всё кроме этих двух команд
21:


Мне собственно было бы всё равно, если б цикл выполнялся правильно,
но он зависает в бесконечном цикле!!!
как в этом может быть ошибка???
Цитата
U8 i
for(i = 0; i < 255; i++);//задержка


ЗЫ Кейл юВижн 3.6
тау
В старину , на 2-м кейле это выглядело так:

Код
43   1      for(R=247;R>0;R--) {_nop_();_nop_();}
///////
листинг
;---- Variable 'R' assigned to Register 'R7' ----
002E 7FF7              MOV     R7,#0F7H
0030         ?C0001:
0030 00                NOP    
0031 00                NOP    
0032 DFFC              DJNZ    R7,?C0001
scifi
Цитата(greatbaobab @ Apr 25 2010, 11:35) *
как в этом может быть ошибка???

Легко. Что-то я после "U8 i" не вижу точку с запятой. К тому же где typedef для "U8"? Там всё в порядке? Может быть, слово "for" переопределено при помощи #define каким-нибудь врагом?
Короче, возможностей много.
Сергей Борщ
Цитата(greatbaobab @ Apr 25 2010, 10:35) *
который я бы "скомпилировал" бы так
Я бы на месте компилятора вообще выкинул этот код, поскольку он не делает ничего полезного с точки зрения стандарта. И многие компиляторы такой код выкидывают при включенной оптимизации. Во избежание сюрпризов объявите i как volatile
Палыч
Возможно, что Вы запутались в коде, генерируемом транслятором: приведенный ассемблерный текст не соответствует этому тексту языка Си. У меня получается вполне ожидаемое
Код
;---- Variable 'i' assigned to Register 'R7' ----
0000 E4                CLR     A
0001 FF                MOV     R7,A
0002         ?C0001:
0002 0F                INC     R7
0003 BFFFFC            CJNE    R7,#0FFH,?C0001

Включите генерацию листинга и ассемблерного кода
AndreyS
Добрый день.

Хе хе smile.gif Не злобы ради и не для рекламы Onembedding

Для того что бы получить в коде конструкцию на DJNZ
Код
unsigned char i;

i=0;
do{

}while(--i);


В общем в Keil для 8051 идет прямая интерпретация. Типа если хотим DJNZ, то по смыслу нужно ставить именно преддекремент.

По этой причине лучше всегда использовать развернутый код (ну не сворачивать в одну строку. Конечно на Си будет компактно, но компилятор наворотит такой код что просто жуть. И никакая оптимизация по размеру не поможет). Проверял на собственном опыте. Просто подизассемблите разные куски кода на Си. И зависимость сразу увидите.

PS Ой и совсем забыл. Все зависит от модели памяти. Для однозначности переменную пихаем в регистр.
Код
[b]register[/b]unsigned char i;

А то если ваша переменная окажется в области xdata то без перегрузки в регистр Keil еще круче наворотит. Будет постоянно обращаться к xdata через DPTR. Если переменная будет в PDATA то хоть @R0 будет использовать.
scifi
Цитата(AndreyS @ Apr 26 2010, 12:19) *
По этой причине лучше всегда использовать развернутый код (ну не сворачивать в одну строку. Конечно на Си будет компактно, но компилятор наворотит такой код что просто жуть. И никакая оптимизация по размеру не поможет). Проверял на собственном опыте. Просто подизассемблите разные куски кода на Си. И зависимость сразу увидите.

Это, наверное, оффтопик, но сказать хочется. Подгонять код на Си в целях потакания тупизму отдельно взятого компилятора - неблагодарная работа. Я уверен, что это время можно потратить гораздо эффективнее. Ну а если нужен хороший код, а компилятор тупит, - тогда ассемблер вам в руки.
Палыч
Цитата(AndreyS @ Apr 26 2010, 12:19) *
По этой причине лучше всегда использовать развернутый код (ну не сворачивать в одну строку. Конечно на Си будет компактно, но компилятор наворотит такой код что просто жуть. И никакая оптимизация по размеру не поможет). Проверял на собственном опыте. Просто подизассемблите разные куски кода на Си. И зависимость сразу увидите.
Не замечал, чтобы Keil генерил какой-то невнятный код. Конечно, иногда транслятору нужно подсказать, например, в какую память распределить те или иные данные... А, по поводу оптимизации в Keil: при установке уровня оптимизации нужно смотреть, что Вы заставляете транслятор оптимизировать (неплохо бы почитать об этом в документации), а не ставить тупо, например, "Level 9"...
AndreyS
Цитата(Палыч @ Apr 26 2010, 17:02) *
Не замечал, чтобы Keil генерил какой-то невнятный код. Конечно, иногда транслятору нужно подсказать, например, в какую память распределить те или иные данные... А, по поводу оптимизации в Keil: при установке уровня оптимизации нужно смотреть, что Вы заставляете транслятор оптимизировать (неплохо бы почитать об этом в документации), а не ставить тупо, например, "Level 9"...


День добрый.

Офтопик.

Я в общем то говорил о том, что Keil использует одни и те же конструкции при одном и том же типе памяти. И оптимизация может помочь немного. Но оптимально получается сразу использовать определенные конструкции на Си. Все это (лично мое мнение) я отношу именно для Си под 8051 и его системе команд. Стандарт Си, на сколько мне известно, не определяет как конкретно реализовывать код в машинных кодах.
редактор
Мое мнение: так как Кейл не знает тип U8 то переменную взял как int(наверняка при компиляции выдал предупреждение).
Соответственно инкремент и сравнение идут для знакового двухбайтового числа.
Все логично.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.