|
Кривизна HI-TECH C |
|
|
|
Sep 12 2011, 04:35
|
Местный
  
Группа: Свой
Сообщений: 454
Регистрация: 13-10-10
Из: Киев
Пользователь №: 60 135

|
Здравствуйте! Пытался скомпилировать простенькую програмку на С для ПИК10, вот её листинг: Код #include <htc.h> #define _XTAL_FREQ 4000000 __CONFIG(WDT_OFF&CP_ON&MCLRE_OFF); void main(void){ __delay_ms(50); GP1=1; TRIS=0b1101; while(GP0=1){} __delay_ms(4000); GP1=0; __delay_ms(300); GP1=1; } После компиляции просмотрел дизассембилованый листинг и не понял зачем копилятор проверку while(GP0=1){} заменил на 8 строчек кода: Код 11 A13 GOTO 0x13 12 A13 GOTO 0x13 13 506 BSF 0x6, 0 14 606 BTFSC 0x6, 0 15 A17 GOTO 0x17 16 A18 GOTO 0x18 17 A13 GOTO 0x13 18 A19 GOTO 0x19 Хотя по моему пониманию можно было обойтись двумя Код 11 606 BTFSC 0x6, 0 12 A11 GOTO 0x11 И зачем он в коде делает операцию BSF 0x6, 0 ? И заодно можно ли в MPLAB'е удобно вытянуть дизассемблированый листинг (не так как я привёл выше, а чисто ассемблер без обозначений номера строки и кода)? Чтоб мои предположения быстренько на асме проверить. Заранее спасибо за комментарии и ответы.
Сообщение отредактировал kt368 - Sep 12 2011, 04:50
|
|
|
|
|
Sep 12 2011, 05:24
|
Профессионал
    
Группа: Свой
Сообщений: 1 047
Регистрация: 28-06-07
Из: Israel
Пользователь №: 28 763

|
Цитата и не понял зачем копилятор проверку while(GP0=1){} заменил на 8 строчек кода: Это "сырой" код, если включить оптимизацию - все будет нормально. Для 16-х - ХайТечь отличный компилятор, и его код почти не уступает ассемблеру, не думаю что 10-е чем-то отличаются.
|
|
|
|
|
Sep 12 2011, 06:13
|

Частый гость
 
Группа: Свой
Сообщений: 194
Регистрация: 14-02-07
Из: УКРАИНА
Пользователь №: 25 344

|
Цитата(kt368 @ Sep 12 2011, 08:27)  А как включить оптимизацию? Если в MPLAB IDE то опции проекта -> вкладка компилятора и линкера - можно свои опции оптимизации и глубину установить, в PDF описании опции командной строки очень подробно описаны если из другими средсвами компиляция управляется.
--------------------
"Для того чтобы избежать критики, надо ничего не делать, ничего не говорить и никем не быть" "Каждый из нас бывает дураком по крайней мере пять минут в день; мудрость заключается в том, чтобы не превысить лимит." Элберт Хаббард
|
|
|
|
|
Sep 12 2011, 06:21
|

Гуру
     
Группа: Участник
Сообщений: 2 254
Регистрация: 4-05-07
Из: Moscow
Пользователь №: 27 515

|
Цитата while(GP0=1) Это вовсе не проверка. И компилятор наверняка выдал на эту строчку предупреждение. while (GP==1) {} - вот это проверка.
--------------------
On the road again (Canned Heat)
|
|
|
|
|
Sep 12 2011, 07:18
|
Местный
  
Группа: Свой
Сообщений: 454
Регистрация: 13-10-10
Из: Киев
Пользователь №: 60 135

|
Точно! Блин, перепутал! Спасибо большое! Но всё равно теперь имеем Код 11 A13 GOTO 0x13 12 A13 GOTO 0x13 13 606 BTFSC 0x6, 0 14 A16 GOTO 0x16 15 A17 GOTO 0x17 16 A13 GOTO 0x13 17 A18 GOTO 0x18 вместо двух вышеописанных строчек. Как ни игрался с настройками компиляции (Optimization settings в вкладке Compiler окна Build Options) - всё равно код на ассемблере кривой. Пробовал уже и Код if (GP0==1) {} else { __delay_ms(4000); GP1=0; __delay_ms(300); GP1=1; } Всё равно ассемблер кривой: Код 11 706 BTFSS 0x6, 0 12 A14 GOTO 0x14 13 A15 GOTO 0x15 14 A17 GOTO 0x17 15 A33 GOTO 0x33 16 A33 GOTO 0x33 Тут 0x33 - последняя строчка программы, Код 33 A02 GOTO 0x2 а 0х17 - то что в теле else. Могу весь проект выложить, хотя его и проектом-то сложно назвать.... И как всё-таки вытащить из MPLAB'а дизассемблированный код? Чтоб его засунуть в проектик на асме.
Сообщение отредактировал kt368 - Sep 12 2011, 07:42
|
|
|
|
|
Sep 12 2011, 09:02
|
Местный
  
Группа: Свой
Сообщений: 454
Регистрация: 13-10-10
Из: Киев
Пользователь №: 60 135

|
Я не тягаюсь, Вы что =) Просто непонятно, где тут идеальность? Почему нельзя было просто сделать как я написал в первом сообщении: Код 11 606 BTFSC 0x6, 0 12 A11 GOTO 0x11 Это ж две строчки выходят, и, как я понимаю, они полностью соответствуют Код while(GP0==1){}
|
|
|
|
|
Sep 12 2011, 10:20
|
Гуру
     
Группа: Свой
Сообщений: 2 360
Регистрация: 6-03-06
Из: Кишинев
Пользователь №: 15 025

|
Цитата(kt368 @ Sep 12 2011, 12:02)  Я не тягаюсь, Вы что =) Просто непонятно, где тут идеальность? Почему нельзя было просто сделать как я написал в первом сообщении: Код 11 606 BTFSC 0x6, 0 12 A11 GOTO 0x11 Это ж две строчки выходят, и, как я понимаю, они полностью соответствуют Код while(GP0==1){} нет, они полностью соответствуют Код while(GP0==1){}; или Код while(GP0==1); Найдите разницу. На будущее, если вы склонны делать ошибки типа "=" вместо "==" и не обращать внимание на варнинги, лучше в операторах сравнения слева пишите константу а справа переменную, тогда компилятор сразу покажет плохое место. то есть Код while(1==GP0){}; Общее замечание: каждый возникший при компиляции варнинг должен быть рассмотрен и по возможности исправлен. Часто встречал случаи, когда неправильно работающая программа после "работы над варнингами" начинала работать так как хотелось автору этой программы, и компилятор тут не виноват.
|
|
|
|
|
Sep 12 2011, 12:05
|
Местный
  
Группа: Свой
Сообщений: 454
Регистрация: 13-10-10
Из: Киев
Пользователь №: 60 135

|
Не понял про Код while(GP0==1); и Код while(GP0==1){}; Разжуйте пожалуйста
|
|
|
|
|
Sep 12 2011, 13:06
|
Гуру
     
Группа: Свой
Сообщений: 2 360
Регистрация: 6-03-06
Из: Кишинев
Пользователь №: 15 025

|
Цитата(kt368 @ Sep 12 2011, 15:05)  Не понял про Код while(GP0==1); и Код while(GP0==1){}; Разжуйте пожалуйста Хм. Ошибся. зачеркните. (Подумалось что так как нет точки запятой то он delay включил в тело цикла, и эти goto как раз и есть delay). Просто я никогда не пропускал разделительную точку с запятой, которая у вас отсутствует, вот и подумал что непонятный эффект из-за этого. Оказалось, что неправ (счас поверил, правдо на хайтече для 18-х, но это непринципиально. но для 18-х он goto не вставляет). А у вас он похоже просто выравнивание по циклам делает. Приходится догадываться что от чего сгенерилось, если бы вы могли просто кусок листинга привести- было бы проще (View->Disassembly Listing в МПЛАБе)
|
|
|
|
|
Sep 12 2011, 13:12
|
Местный
  
Группа: Свой
Сообщений: 454
Регистрация: 13-10-10
Из: Киев
Пользователь №: 60 135

|
Да, конечно же. Вот си: Код #include <htc.h> #define _XTAL_FREQ 4000000 __CONFIG(WDT_OFF&CP_ON&MCLRE_OFF); void main(void){ __delay_ms(50); GP1=1; TRIS=0b1101; while(GP0==1){}; __delay_ms(4000); GP1=0; __delay_ms(300); GP1=1; } Вот асм: Код --- C:\D\Projects\MB start\with PIC10F200\C\main.c --------------------------------------------- 1: #include <htc.h> 2: #define _XTAL_FREQ 4000000 3: __CONFIG(WDT_OFF&CP_ON&MCLRE_OFF); 4: void main(void){ 5: __delay_ms(50); 05 C41 MOVLW 0x41 06 031 MOVWF 0x11 07 CEE MOVLW 0xee 08 030 MOVWF 0x10 09 2F0 DECFSZ 0x10, F 0A A09 GOTO 0x9 0B 2F1 DECFSZ 0x11, F 0C A09 GOTO 0x9 0D 004 CLRWDT 6: GP1=1; 0E 526 BSF 0x6, 0x1 7: TRIS=0b1101; 0F C0D MOVLW 0xd 10 006 TRIS 0x6 8: while(GP0==1){}; 11 A13 GOTO 0x13 12 A13 GOTO 0x13 13 606 BTFSC 0x6, 0 14 A16 GOTO 0x16 15 A17 GOTO 0x17 16 A13 GOTO 0x13 17 A18 GOTO 0x18 9: __delay_ms(4000); 18 C15 MOVLW 0x15 19 032 MOVWF 0x12 1A C4B MOVLW 0x4b 1B 031 MOVWF 0x11 1C CD1 MOVLW 0xd1 1D 030 MOVWF 0x10 1E 2F0 DECFSZ 0x10, F 1F A1E GOTO 0x1e 20 2F1 DECFSZ 0x11, F 21 A1E GOTO 0x1e 22 2F2 DECFSZ 0x12, F 23 A1E GOTO 0x1e 24 004 CLRWDT 10: GP1=0; 25 426 BCF 0x6, 0x1 11: __delay_ms(300); 26 C02 MOVLW 0x2 27 032 MOVWF 0x12 28 C86 MOVLW 0x86 29 031 MOVWF 0x11 2A C99 MOVLW 0x99 2B 030 MOVWF 0x10 2C 2F0 DECFSZ 0x10, F 2D A2C GOTO 0x2c 2E 2F1 DECFSZ 0x11, F 2F A2C GOTO 0x2c 30 2F2 DECFSZ 0x12, F 31 A2C GOTO 0x2c 12: GP1=1; 32 526 BSF 0x6, 0x1 13: } 33 A02 GOTO 0x2
|
|
|
|
|
Sep 12 2011, 13:19
|
    
Группа: Свой
Сообщений: 1 928
Регистрация: 11-07-06
Пользователь №: 18 731

|
Цитата(kt368 @ Sep 12 2011, 16:05)  Разжуйте пожалуйста В данном случае - одинаково (по синтаксису С - одинаково небрежно, корректней "while(GP0==1) continue;"). Проблемы могут возникнуть при использовании макросов с do. В main() имеет смысл организовать бесконечный цикл - без него после последнего оператора в main() компилятор добавляет переход на init(). И указывайте версию компилятора. 9.82 любые Ваши вариации на тему while(GP0==1) компилит в "btfsc ...; goto $-1", а более ранние версии могли и почудесатей изобразить. Цитата И как всё-таки вытащить из MPLAB'а дизассемблированный код? Проще попросить компилятор сделать .as (в МПЛаб в окне проекта ПКМ на .c -> Compile to .as). ЗЫЖ если Вам лень ручками отрезать от картинки по PrtSc лишнее, пользуйтесь Alt+PrtSc.
|
|
|
|
|
Sep 12 2011, 21:22
|

Универсальный солдатик
     
Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362

|
Тот же код, MPLAB 8.76, Hi-Tech 9.82. Код 12: #include <htc.h> 13: #define _XTAL_FREQ 4000000 14: __CONFIG(WDT_OFF & CP_ON & MCLRE_OFF); 15: 16: void main(void){ 17: __delay_ms(50); 05 C41 MOVLW 0x41 06 031 MOVWF 0x11 07 CEE MOVLW 0xee 08 030 MOVWF 0x10 09 2F0 DECFSZ 0x10, F 0A A09 GOTO 0x9 0B 2F1 DECFSZ 0x11, F 0C A09 GOTO 0x9 0D 004 CLRWDT 18: GP1=1; 0F 526 BSF 0x6, 0x1 19: TRIS=0b1101; 0E C0D MOVLW 0xd 10 006 TRIS 0x6 20: while(GP0==1){}; 11 606 BTFSC 0x6, 0 12 A11 GOTO 0x11 21: __delay_ms(4000); 13 C15 MOVLW 0x15 14 032 MOVWF 0x12 15 C4B MOVLW 0x4b 16 031 MOVWF 0x11 17 CD1 MOVLW 0xd1 18 030 MOVWF 0x10 19 2F0 DECFSZ 0x10, F 1A A19 GOTO 0x19 1B 2F1 DECFSZ 0x11, F 1C A19 GOTO 0x19 1D 2F2 DECFSZ 0x12, F 1E A19 GOTO 0x19 1F 004 CLRWDT 22: GP1=0; 21 426 BCF 0x6, 0x1 23: __delay_ms(300); 20 C02 MOVLW 0x2 22 032 MOVWF 0x12 23 C86 MOVLW 0x86 24 031 MOVWF 0x11 25 C99 MOVLW 0x99 26 030 MOVWF 0x10 27 2F0 DECFSZ 0x10, F 28 A27 GOTO 0x27 29 2F1 DECFSZ 0x11, F 2A A27 GOTO 0x27 2B 2F2 DECFSZ 0x12, F 2C A27 GOTO 0x27 24: GP1=1; 2D 526 BSF 0x6, 0x1 25: } 2E A02 GOTO 0x2 Ответ - в настройках. У топикстартера явно не используется PRO режим компилятора. Насчет ассемблерного представления, еще один вариант View -> Program Memory.
|
|
|
|
2 чел. читают эту тему (гостей: 2, скрытых пользователей: 0)
Пользователей: 0
|
|
|