Перейти к содержанию
    

проблема с компилятором

Проблема с Си кодом.

До этого писал все программы на Асемблере. Решил написать программу на Си. Написал - не работает. Начал разбираться и понял, что компилириет не правильно, неу или не так как мне надо (как я думал). Помогите разобраться, что я делаю не так.

В низу приведен код который компилируется не так (пример).

 

/////////////////////////////////////////////////////////////////////////////

Текст программы (С-код):

 

#include <avr/io.h>

int main(void)
{
 int q, w, e;

while(1)
{
e=1;
 do 
 {
 q=q+1;
 w=q+1;		 
e=w-e; 
 } while (q<50);
 e=2;
  do
  {
	  q=q+1;
	  w=q+1;
	  e=w-e;
  } while (w<150);  
	//TODO:: Please write your application code 
}
}

 

//////////////////////////////////////////////////////////////

Lss файл:

 

 

000001f4 <__ctors_end>:
1f4:	11 24       	eor	r1, r1
1f6:	1f be       	out	0x3f, r1	; 63
1f8:	cf ef       	ldi	r28, 0xFF	; 255
1fa:	df e3       	ldi	r29, 0x3F	; 63
1fc:	de bf       	out	0x3e, r29	; 62
1fe:	cd bf       	out	0x3d, r28	; 61
200:	00 e0       	ldi	r16, 0x00	; 0
202:	0c bf       	out	0x3c, r16	; 60
204:	18 be       	out	0x38, r1	; 56
206:	19 be       	out	0x39, r1	; 57
208:	1a be       	out	0x3a, r1	; 58
20a:	1b be       	out	0x3b, r1	; 59
20c:	02 d0       	rcall	.+4      	; 0x212 <main>
20e:	0f c0       	rjmp	.+30     	; 0x22e <_exit>

00000210 <__bad_interrupt>:
210:	f7 ce       	rjmp	.-530    	; 0x0 <__vectors>

00000212 <main>:

e=1;

 do 
 {
	 q=q+1;
212:	01 96       	adiw	r24, 0x01	; 1

	 w=q+1;		 

	e=w-e; 

 } while (q<50);
214:	82 33       	cpi	r24, 0x32	; 50
216:	91 05       	cpc	r25, r1
218:	e4 f3       	brlt	.-8      	; 0x212 <main>
*/ 


#include <avr/io.h>

int main(void)
21a:	9c 01       	movw	r18, r24
21c:	2f 5f       	subi	r18, 0xFF	; 255
21e:	3f 4f       	sbci	r19, 0xFF	; 255

 e=2;

  do
  {
	  q=q+1;
220:	c9 01       	movw	r24, r18
222:	2f 5f       	subi	r18, 0xFF	; 255
224:	3f 4f       	sbci	r19, 0xFF	; 255

	  w=q+1;

	  e=w-e;

  } while (w<150);  
226:	26 39       	cpi	r18, 0x96	; 150
228:	31 05       	cpc	r19, r1
22a:	d4 f3       	brlt	.-12     	; 0x220 <main+0xe>
22c:	f2 cf       	rjmp	.-28     	; 0x212 <main>

0000022e <_exit>:
22e:	f8 94       	cli

00000230 <__stop_program>:
230:	ff cf       	rjmp	.-2      	; 0x230 <__stop_program>

////////////////////////////////////////////////////////////////////////////////////////////

 

Вообще если вставить в программу цикл while, то начинает компилировать не правильно.

 

В чем проблема.

Изменено пользователем IgorKossak
[codebox] для длинного кода, [code] - для короткого!!!

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Перво-наперво читать от корки до корки:

http://www.nongnu.org/avr-libc/user-manual/FAQ.html

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Первоначальные значения q и w не заданы.

Это уже не столь принципиально, т.к. при включении оптимизации весь код ТС будет выкинут...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Перво-наперво читать от корки до корки:

http://www.nongnu.org/avr-libc/user-manual/FAQ.html

 

Да, сделал все переменные volatile и определил их в начале и все заработало.

 

Можно отключить оптимизацию компилятора вообще?

 

А есть какая-нибудь книжка по Си для АВР (GCC). ?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Да, сделал все переменные volatile и определил их в начале и все заработало.
Ответьте себе на вопрос: что должна была сделать ваша программа полезного? Ответ - ничего. Что компилятор и сделал.

Тупое припысывание volatile всем подряд переменным, перенос определения куда-нибудь, где заработает, отключение оптимизации - это все больше похоже на действия персонажа басни Крылова "Мартышка и очки".

 

А есть какая-нибудь книжка по Си для АВР (GCC). ?
Это примерно как "чернила для второго класса". Си он и есть Си.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А есть какая-нибудь книжка по Си для АВР (GCC). ?

Лучше обращаться к первоисточникам:

http://www.nongnu.org/avr-libc/user-manual/pages.html

http://www.nongnu.org/avr-libc/user-manual/group__demos.html

http://gcc.gnu.org/onlinedocs/gcc-4.4.7/gcc/

https://ru.wikipedia.org/wiki/C99 (внизу страницы есть ссылка на черновик стандарта в pdf формате)

Можно отключить оптимизацию компилятора вообще?
Можно, но этого никогда не стоит делать.

Задайте уровень оптимизации Os и больше никогда не меняйте - это наиболее оптимальный вариант для avr-gcc (проверено миллионами мух:))

Чтобы проверить работу алгоритма по дизассемблеру, выводите результаты вычислений внутри тела цикла в порт, например

 PORTD = (uint8_t)fabsf(sinf(x)/33.0f+y);

PORTD - это регистр области SFR и описан он как волатильный, поэтому компилятор не будет ничего выкидывать...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

 

Гуру !!! из Латвии ???? по ответу заметно.

 

И тебе спасибо добрый человек......

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Гуру !!! из Латвии ???? по ответу заметно.
Еще раз повторю вопрос:

Что полезного должна была сделать эта программа? Иными словами - как используется результат вычислений? Ответ - никак не используется. Значит он не нужен. Раз он не нужен, то его вычисление - бесполезная трата времени. Компилятор сделал вашу большую медленную программу маленькой и быстрой, при этом результат ее работы не изменился - он как был никаким, так никаким и остался. И когда вы поймете, что компилятор сделал именно то, что вы просили - вы перестанете искать ошибки там, где их нет и начнете изучать язык чтобы правильно объяснить компилятору на его языке чего именно вы хотите.

 

Проблема в вашем коде не "с компилятором", а в том, что вы не понимаете, что целью программы на языке высокого уровня является не передвигание байтов, а получение конечного результата алгоритма. И может даже не тем способом, который вы описали в алгоритме. Главное - что будет получен тот же самый результат что и для описанного в исходном коде алгоритма.

 

Добавлением volatile куда попало методом тыка вы как бы сказали, что результат любого промежуточного вычисления может в любой момент неожиданно понадобится неочевидным компилятору образом (например, прерыванию или отраженному на память внешнему устройству) и компилятор вынужден складывать в память все промежуточные результаты, вместо того, чтобы максимально быстрым и/или коротким способом получить тот результат, который вам действительно будет нужен после выполнения этого участка кода.

 

Или вы будете утверждать, что "сделал все переменные volatile" - это осознанное действие и вы можете обосновать необходимость volatile для каждой из этих переменных? Нет, не можете.

Вертит Очками так и сяк:

То к темю их прижмет, то их на хвост нанижет,

То их понюхает, то их полижет;

Разве не похоже?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

> И тебе спасибо добрый человек......

Рад помочь. Форум для того и нужен - поднимать уровень образования и культуры.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...