0 / 0 / 0
Регистрация: 29.03.2010
Сообщений: 44
|
|
1 | |
Как бороться с внезапной ассемблерной вставкой?07.01.2012, 21:47. Показов 6407. Ответов 17
Метки нет (Все метки)
Есть программа, написанная на Си, рабочая.
Для отладки программы использовал 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(); } } Код
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(); Почему такое происходит, и как от этого избавиться?
0
|
07.01.2012, 21:47 | |
Ответы с готовыми решениями:
17
Ввод числа ассемблерной вставкой (вызов scanf из ассемблерной вставки) Как вызвать CreateFile ассемблерной вставкой? Как написать программу на C++ с ассемблерной вставкой? Как очистить консоль ассемблерной вставкой? С++ с Ассемблерной вставкой |
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
0
|
0 / 0 / 0
Регистрация: 27.06.2010
Сообщений: 405
|
|
07.01.2012, 22:48 | 5 |
Сообщение от Wroyth
А по существу вопроса, действительно похоже на пропущенный 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
ИМХО неплохо удостоверится, что код хотя-бы полностью синтаксически корректен (читай компилируется) и в отладочной и в финальной версии одновременно. В случае #ifdef программу для этого нужно скомпилировать дважды (а если есть еще и несколько уровней отладки...) с разными ключами. В случае с if - достаточно одного раза. По-моему одного этого факта достаточно, чтоб использовать if с константным выражением вместо препроцессора для подобных целей. Теперя панимать?
0
|
0 / 0 / 0
Регистрация: 07.04.2011
Сообщений: 663
|
|
08.01.2012, 00:05 | 9 |
Сообщение от miyvir
Как по мне, так одно и тоже, просто с #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
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
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
0
|
10.01.2012, 01:21 | |
10.01.2012, 01:21 | |
Помогаю со студенческими работами здесь
18
Код с ассемблерной вставкой Ошибка с ассемблерной вставкой Lazarus с Ассемблерной вставкой Найти F(x) = x^3/(x^2+1) ассемблерной вставкой в С Декремент с ассемблерной вставкой Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |