Форум программистов, компьютерный форум, киберфорум
Микроконтроллеры ATmega AVR
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.91/35: Рейтинг темы: голосов - 35, средняя оценка - 4.91
0 / 0 / 0
Регистрация: 29.03.2010
Сообщений: 44
1

Как бороться с внезапной ассемблерной вставкой?

07.01.2012, 21:47. Показов 6407. Ответов 17
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Есть программа, написанная на Си, рабочая.
Для отладки программы использовал 16х2-дисплей. Т.к. программа написана, необходимо убрать этот дисплей.
Чтобы это можно было сделать быстро, везде, где он используется, писал так:
Код
if (LCD_YES)
{
lcd_puts("Не важно что")
}
и в самом начале листинга соотвественно
Код
define LCD_YES   1
где можно быстро включать-выключать дисплей.

Суть вот в чем - ни разу я его не отключал (да и зачем было?), программа написана, пришло время поставить вместо единицы нолик, что и было сделано. И тут программа перестала работать.

Код
int main(void)
{
Init();                  // инициализация портов, таймеров и др.
RecipientComplete = 0;      // обнуляем флаг приемки данных
PORTC &= ~(1<<SIM900D_ON);      // Включаем SIM900D - сажаем на "0" выход для открытия транзистора
PORTC |= (1<<PWR_KEY);
PORTC &= ~(1<<PWR_KEY);
while(1)
{
nop();
if (RecipientComplete == 1)               // Если пришла посылка от SIM900D
{
ReceiveAnalysis(rx_buffer);            // Анализируем
}
nop();
}
}
Шерстя по ассемблерному коду, увидел, что перед while(1) появился такой код:
Код
945:         PORTC &= ~(1<<PWR_KEY);
+0000059C:   98AF        CBI       0x15,7         Clear bit in I/O rikystir
952:            nop();
+0000059D:   0000        NOP                      No operation
953:            nop();
+0000059E:   0000        NOP                      No operation
958:            nop();
+0000059F:   0000        NOP                      No operation
+000005A0:   CFFC        RJMP      PC-0x0003      Relative jump
958:            nop();
самого while() нету, да собственно и не нужен, т.к. RJMP PC-0x0003 зацикливает программу на месте между nopами.

Почему такое происходит, и как от этого избавиться?
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
07.01.2012, 21:47
Ответы с готовыми решениями:

Ввод числа ассемблерной вставкой (вызов scanf из ассемблерной вставки)
Здравствуйте! Задача: Напишите программу, в которой создается и заполняется натуральными числами...

Как вызвать CreateFile ассемблерной вставкой?
нужно открыть устройство с помощью createfile ассемблерной вставкой, пока ничего не вышло решил...

Как написать программу на C++ с ассемблерной вставкой?
слышал,что возможно,но не имею представления,как это делаеться

Как очистить консоль ассемблерной вставкой?
собственно, аналог system(&quot;clr&quot;); только ассемблеровской вставкой ...

С++ с Ассемблерной вставкой
помогите с решением данного задания Y = b-a-c+d

17
0 / 0 / 0
Регистрация: 10.08.2010
Сообщений: 1,264
07.01.2012, 22:05 2
RecipientComplete не volatile.
0
1 / 1 / 0
Регистрация: 28.01.2010
Сообщений: 537
07.01.2012, 22:10 3
Компиль "почесав репу", подумал (RecipientComplete = 0) и не меняется по ходу выполнения проги,
то условие всегда не выполняется и выкинул его содержимое нах.
Вот таким чудным образом мы и получили пустой цикл.
0
0 / 0 / 0
Регистрация: 07.04.2011
Сообщений: 663
07.01.2012, 22:19 4
ну про volatile уже сказали :)
а #define LCD_YES 1 можно писать записать так:

Код
#define LCD_YES

#ifdef LCD_YES
lcd_puts("Не важно что")
#endif
Просто в вашем случае lcd_puts("Не важно что") - выкинет компилятор, а в #ifdef - препроцессор. Хотя, на конечном результате это никак не скажется, скорее всего.
0
0 / 0 / 0
Регистрация: 27.06.2010
Сообщений: 405
07.01.2012, 22:48 5
Цитата Сообщение от Wroyth
Просто в вашем случае lcd_puts("Не важно что") - выкинет компилятор, а в #ifdef - препроцессор. Хотя, на конечном результате это никак не скажется, скорее всего.
Вариант с обычным if идеологически правильнее, чем с #ifdef потому, что прежде чем выкинуть недостижимый код, компилятор всё-таки проверит его корректность, в отличии от препроцессора.
А по существу вопроса, действительно похоже на пропущенный volatile.
0
0 / 0 / 0
Регистрация: 21.10.2011
Сообщений: 1,860
07.01.2012, 23:00 6
вариант с IF идеологически идиотизм, если значение нигде не меняется. и компилятор поступил абсолютно верно. если так уже сильно хочется, для GCC ключик -O0, для остальных посмотреть, где отключить оптимизацию.
зачем проверять код, который никогда не будет вызван? мая нипанимать!.. %)
0
0 / 0 / 0
Регистрация: 29.03.2010
Сообщений: 44
07.01.2012, 23:21 7
Гениально :)
Всем спасибо, помогло.
0
0 / 0 / 0
Регистрация: 27.06.2010
Сообщений: 405
07.01.2012, 23:55 8
Цитата Сообщение от tid_fom
вариант с IF идеологически идиотизм, если значение нигде не меняется. и компилятор поступил абсолютно верно. если так уже сильно хочется, для GCC ключик -O0, для остальных посмотреть, где отключить оптимизацию.
зачем проверять код, который никогда не будет вызван? мая нипанимать!.. %)
Зачем вообще писать код который никогда не будет вызван? Или всё-таки если он написан, то он иногда вызывается?
ИМХО неплохо удостоверится, что код хотя-бы полностью синтаксически корректен (читай компилируется) и в отладочной и в финальной версии одновременно. В случае #ifdef программу для этого нужно скомпилировать дважды (а если есть еще и несколько уровней отладки...) с разными ключами. В случае с if - достаточно одного раза. По-моему одного этого факта достаточно, чтоб использовать if с константным выражением вместо препроцессора для подобных целей.
Теперя панимать?
0
0 / 0 / 0
Регистрация: 07.04.2011
Сообщений: 663
08.01.2012, 00:05 9
Цитата Сообщение от miyvir
В случае #ifdef программу для этого нужно скомпилировать дважды
А можно вот тут поподробнее? На сколько я понимаю - препроцессор смотрит значение #ifdef и если оно не выполняется - выкидывает все до #endif неглядя - а затем скармливает все что осталось компилятору. в случае с if он подставляет значение и тоже потом скармливает компилятору, который видя, что условие всегда ложно, выкидывает кусок кода сам.

Как по мне, так одно и тоже, просто с #ifdef я точно указываю границы кода, который мне не нужен (а там может быть и несколько процедур - например работы UART ), не полагаясь на компилятор, который процедуру, может и не выбросить (к примеру). Имхо.

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

Код
#define UART_SPAM

#if defined (UART_SPAM)

void uart_init(void)
{
cli();
UCSRB |= (1<<RXEN)|(1<<TXEN)|(1<<RXCIE); // UART TX Activate
UCSRC |= (1<<UCSZ1)|(1<<UCSZ0); // Asynchrony 8N1
UBRRH = (unsykned char) (UBRR << 8); // 56000 Baud Rate on 8 Mhz
UBRRL = (unsykned char) (UBRR);
sei();
}

//Функция отправки данных UART
void USORT_Transmit(char data)
{
while ( !(UCSRA & (1<<UDRE)) ); //Ожидание опустошения буфера приема
UDR = data; //Начало передачи данных
}

//Функция отправки сообщения
void msgout (char *msg)
{
while (*msg!=\0)   // Пока первый байт строки не 0
{
USORT_Transmit(*msg);
msg++;
}
}

void msgoutln (char *msg)
{
while (*msg!=\0)
{
USORT_Transmit(*msg);
msg++;
}
USORT_Transmit(0x0D);
USORT_Transmit(0x0A);
}

#endif
0
0 / 0 / 0
Регистрация: 27.06.2010
Сообщений: 405
08.01.2012, 01:07 10
В вашем случае получается ДВЕ программы с разной функциональностью, которые компилируются из одних исходников. Одна - если символ UART_SPAM определен, вторая - если нет. Понятно, что для проверки синтаксической корректности кода внутри блока #if defined (UART_SPAM), нужно определить символ UART_SPAM. А вот для проверки явных, или, еще хуже, скрытых зависимостей от условно компилируемого кода в основной программе, её нужно еще раз компилировать с не определенным UART_SPAM.
А если таких параметров как UART_SPAM штук 5,10,20...? Сколько раз нужно скомпилировать исходники, чтоб убедиться, что они просто компилируются (про работают я не говорю) с любой допустимой комбинацией параметров?
0
0 / 0 / 0
Регистрация: 07.04.2011
Сообщений: 663
08.01.2012, 01:44 11
Ага, кажется я вашу мысль понял :)

На самом деле я сначала полностью написал и отладил программу, а потом просто добавил этот флаг, т.к. планирую перевести в железо, а там только расход батареи будет на UART, и никакой пользы...
Да и программа на сотню-другую строк всего...
0
0 / 0 / 0
Регистрация: 22.08.2009
Сообщений: 525
09.01.2012, 23:02 12
Цитата Сообщение от tid_fom
вариант с IF идеологически идиотизм, если значение нигде не меняется. и компилятор поступил абсолютно верно. если так уже сильно хочется, для GCC ключик -O0, для остальных посмотреть, где отключить оптимизацию.
зачем проверять код, который никогда не будет вызван? мая нипанимать!.. %)
приобрести бубен. Или нет?
0
0 / 0 / 0
Регистрация: 21.10.2011
Сообщений: 1,860
09.01.2012, 23:05 13
каким раком сюда бубен?
0
0 / 0 / 0
Регистрация: 22.08.2009
Сообщений: 525
09.01.2012, 23:11 14
Цитата Сообщение от tid_fom
каким раком сюда бубен?
Давно и широко известный прием. Когда что-то не получается - берешь в руки бубен и пляшешь? Неужели не слышали?
0
0 / 0 / 0
Регистрация: 21.10.2011
Сообщений: 1,860
09.01.2012, 23:30 15
тут не бубен нужен, а букварь для начала.
0
0 / 0 / 0
Регистрация: 22.08.2009
Сообщений: 525
09.01.2012, 23:49 16
Цитата Сообщение от tid_fom
тут не бубен нужен, а букварь для начала.
У одного моего знакомого программа для AVR тоже не заработала, причем проблемы были именно в прерываниях. Ну, думаю, приеду и все ему объясню. Ан нет, не тут то было. Когда я к нему выбрался, оказалась проблема уже решена. Интересуюсь - каким образом? А очень просто - ему другой наш общий знакомый посоветовал отключить оптимизацию. Естественно, действительна причина осталась непонятной. Вот и получается - вместо знаний сплошные заклинания и пляски с бубнами. И самое интересное, что человек, научивший такому заклинанию, при этом учит еще студентов в вузе. Вот и получается, что вместе с дипломом выпускникам вуза надо бубны выдавать, или книги с заклинаниями. И выпускники с удовольствием их возьмут. А предложи им букварь, так чего доброго еще и обидятся. Или нет?
0
0 / 0 / 0
Регистрация: 21.10.2011
Сообщений: 1,860
09.01.2012, 23:58 17
ужас-ужас. не, не так. УЖАС-УЖАС-УЖАС!!!
а бубен часто от банального недостатка знаний и завышенной самооценки. в этом плане мне в свое время очень помогла рекомендация вдумчиво писать, внимательно читать код, всегда включать максимальную оптимизацию и все варнинги. понижение уровня оптимизации - борьба со следствием, а не причиной.

надеюсь, тот знакомый ваял поделку для себя, или лабу какую? а то возможно, что человек, который будет такое чудо сопровождать - может и что тяжелое уронить... ну и вероятность выползания глюка-причины в процессе эксплуатации стремится к единице...
0
0 / 0 / 0
Регистрация: 22.08.2009
Сообщений: 525
10.01.2012, 01:21 18
Цитата Сообщение от tid_fom
ужас-ужас. не, не так. УЖАС-УЖАС-УЖАС!!!
а бубен часто от банального недостатка знаний и завышенной самооценки. в этом плане мне в свое время очень помогла рекомендация вдумчиво писать, внимательно читать код, всегда включать максимальную оптимизацию и все варнинги. понижение уровня оптимизации - борьба со следствием, а не причиной.

надеюсь, тот знакомый ваял поделку для себя, или лабу какую? а то возможно, что человек, который будет такое чудо сопровождать - может и что тяжелое уронить... ну и вероятность выползания глюка-причины в процессе эксплуатации стремится к единице...
мой знакомый делал поделку для себя. И еще про пляски с бубнами http://www.microchip.su/showth... post150219
0
10.01.2012, 01:21
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
10.01.2012, 01:21
Помогаю со студенческими работами здесь

Код с ассемблерной вставкой
Здравствуйте. Помогите, пожалуйста, написать код на си с ассемблерной вставкой к заданию: Дан...

Ошибка с ассемблерной вставкой
#include &lt;iostream&gt; int main() { char src = &quot;hello&quot;, dst; int a = strlen(src); for...

Lazarus с Ассемблерной вставкой
Сижу на паре и вообще не могу понять, как работает лазарус (паскаль) с ассемблерной вставкой ...

Найти F(x) = x^3/(x^2+1) ассемблерной вставкой в С
найти F(x) = x^3/(x^2+1) ассемблерной вставкой в С

Декремент с ассемблерной вставкой
Уважаемые, знатоки, подскажите в чём сакральный смысл такого декремента в программе С++: static...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
18
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru