Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Кривизна HI-TECH C
Форум разработчиков электроники ELECTRONIX.ru > Сайт и форум > В помощь начинающему > MCS51, AVR, PIC, STM8, 8bit
kt368
Здравствуйте!
Пытался скомпилировать простенькую програмку на С для ПИК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'е удобно вытянуть дизассемблированый листинг (не так как я привёл выше, а чисто ассемблер без обозначений номера
строки и кода)? Чтоб мои предположения быстренько на асме проверить.
Заранее спасибо за комментарии и ответы.
Allregia
Цитата
и не понял зачем копилятор проверку while(GP0=1){} заменил на 8 строчек кода:

Это "сырой" код, если включить оптимизацию - все будет нормально.
Для 16-х - ХайТечь отличный компилятор, и его код почти не уступает ассемблеру, не думаю что 10-е чем-то отличаются.
kt368
А как включить оптимизацию?
volodya
Цитата(kt368 @ Sep 12 2011, 08:27) *
А как включить оптимизацию?

Если в MPLAB IDE то опции проекта -> вкладка компилятора и линкера - можно свои опции оптимизации и глубину установить, в PDF описании опции командной строки очень подробно описаны если из другими средсвами компиляция управляется.
DpInRock
Цитата
while(GP0=1)

Это вовсе не проверка.
И компилятор наверняка выдал на эту строчку предупреждение.
while (GP==1) {} - вот это проверка.
kt368
Точно! Блин, перепутал!
Спасибо большое!
Но всё равно теперь имеем
Код
    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'а дизассемблированный код? Чтоб его засунуть в проектик на асме.
DpInRock
Код просто идеальный. Идеальнее не придумаешь.

Вообще, чисто совет. Тягаться в оптимальности с компилятором - надо быть умнее компилятора.
Я еще не встречал людей, которые были бы умнее компилятора.
kt368
Я не тягаюсь, Вы что =)
Просто непонятно, где тут идеальность? Почему нельзя было просто сделать как я написал в первом сообщении:
Код
    11     606     BTFSC 0x6, 0
    12     A11     GOTO 0x11
Это ж две строчки выходят, и, как я понимаю, они полностью соответствуют
Код
while(GP0==1){}
Ruslan1
Цитата(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){};

Общее замечание: каждый возникший при компиляции варнинг должен быть рассмотрен и по возможности исправлен. Часто встречал случаи, когда неправильно работающая программа после "работы над варнингами" начинала работать так как хотелось автору этой программы, и компилятор тут не виноват.
kt368
Не понял про
Код
while(GP0==1);
и
Код
while(GP0==1){};

Разжуйте пожалуйста
Ruslan1
Цитата(kt368 @ Sep 12 2011, 15:05) *
Не понял про
Код
while(GP0==1);
и
Код
while(GP0==1){};

Разжуйте пожалуйста

Хм. Ошибся. зачеркните. (Подумалось что так как нет точки запятой то он delay включил в тело цикла, и эти goto как раз и есть delay). Просто я никогда не пропускал разделительную точку с запятой, которая у вас отсутствует, вот и подумал что непонятный эффект из-за этого. Оказалось, что неправ (счас поверил, правдо на хайтече для 18-х, но это непринципиально. но для 18-х он goto не вставляет).
А у вас он похоже просто выравнивание по циклам делает.
Приходится догадываться что от чего сгенерилось, если бы вы могли просто кусок листинга привести- было бы проще (View->Disassembly Listing в МПЛАБе)
kt368
Да, конечно же.
Вот си:
Код
#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
xemul
Цитата(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.
ViKo
Тот же код, 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.
kt368
Что-то не получается включить 45-day evaluation HI-TECH C PRO Compiler. Жму "Try HI-TECH C PRO" на вкладке "Driver" окна "Build Options", выбираю первый пункт (45-и дневный пробный период), соглашаюсь с лиц. соглашением, жму "OK" далее соглашаюсь с англ. языком, и жму Финиш. Жму ОК, закрываю МПЛАБ, на запрос о сохранении workspace отвечаю да. Запускаю МПЛАБ и ищу в настройках в окне "Build Options" возможность включения компилятора про версии на пробный период, нигде ничего такого не видно. ЧЯДНТ? Или мож его можно де-то ворованый поставить?
ViKo
Цитата(kt368 @ Sep 13 2011, 10:21) *
Что-то не получается включить 45-day evaluation HI-TECH C PRO Compiler.

А у меня вчера получилось. Может быть, у вас 45 дней уже прошли? Или раньше когда-то экспериментировали?
kt368
Хм...а приведите, пожалуйста принтскрин окно, в котором видно, что выбран PRO компилятор.
Allregia
Цитата(kt368 @ Sep 13 2011, 09:21) *
Что-то не получается включить 45-day evaluation HI-TECH C PRO Compiler.


Не надо "Про" он глюкавый, надо STD.
ViKo
Цитата(Allregia @ Sep 13 2011, 16:32) *
Не надо "Про" он глюкавый, надо STD.

Читал подобные высказывания не раз, но сам ни разу не замечал глюков. Может, мне везет? sm.gif
Цитата
Хм...а приведите, пожалуйста принтскрин окно, в котором видно, что выбран PRO компилятор.

А результату компиляции вы не верите? sm.gif
Пишите в мой ящик. Просвещу. sm.gif
volodya
По поводу глюков - в любом компиляторе можно найти (если хорошо копать).
Соглашусь с предыдущим (19) сообщением от ViKo- не встречал, а то что ловил можно считать особенностями оптимизации и исправляется средствами этого - же компилятора или корректным написанием исходных текстов . Хотя нельзя объять необъятное.

На счет лекарства от жадности - и "тута" были выложены и по просторам нета шастали (если надо пиши в личку подскажу).
Хотя правильнее купить или GPL использовать - SDCC for example.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.