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

Здравствуйте!

Пытался скомпилировать простенькую програмку на С для ПИК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

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


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

и не понял зачем копилятор проверку while(GP0=1){} заменил на 8 строчек кода:

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

Для 16-х - ХайТечь отличный компилятор, и его код почти не уступает ассемблеру, не думаю что 10-е чем-то отличаются.

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


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

А как включить оптимизацию?

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

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


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

while(GP0=1)

Это вовсе не проверка.

И компилятор наверняка выдал на эту строчку предупреждение.

while (GP==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

вместо двух вышеописанных строчек. Как ни игрался с настройками компиляции (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

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


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

Код просто идеальный. Идеальнее не придумаешь.

 

Вообще, чисто совет. Тягаться в оптимальности с компилятором - надо быть умнее компилятора.

Я еще не встречал людей, которые были бы умнее компилятора.

 

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


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

Я не тягаюсь, Вы что =)

Просто непонятно, где тут идеальность? Почему нельзя было просто сделать как я написал в первом сообщении:

    11     606     BTFSC 0x6, 0
    12     A11     GOTO 0x11

Это ж две строчки выходят, и, как я понимаю, они полностью соответствуют

while(GP0==1){}

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


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

Я не тягаюсь, Вы что =)

Просто непонятно, где тут идеальность? Почему нельзя было просто сделать как я написал в первом сообщении:

    11     606     BTFSC 0x6, 0
    12     A11     GOTO 0x11

Это ж две строчки выходят, и, как я понимаю, они полностью соответствуют

while(GP0==1){}

нет, они полностью соответствуют

while(GP0==1){};

или

while(GP0==1);

Найдите разницу.

 

На будущее, если вы склонны делать ошибки типа "=" вместо "==" и не обращать внимание на варнинги, лучше в операторах сравнения слева пишите константу а справа переменную, тогда компилятор сразу покажет плохое место. то есть

while(1==GP0){};

Общее замечание: каждый возникший при компиляции варнинг должен быть рассмотрен и по возможности исправлен. Часто встречал случаи, когда неправильно работающая программа после "работы над варнингами" начинала работать так как хотелось автору этой программы, и компилятор тут не виноват.

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


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

Не понял про
while(GP0==1);

и

while(GP0==1){};

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

Хм. Ошибся. зачеркните. (Подумалось что так как нет точки запятой то он delay включил в тело цикла, и эти goto как раз и есть delay). Просто я никогда не пропускал разделительную точку с запятой, которая у вас отсутствует, вот и подумал что непонятный эффект из-за этого. Оказалось, что неправ (счас поверил, правдо на хайтече для 18-х, но это непринципиально. но для 18-х он goto не вставляет).

А у вас он похоже просто выравнивание по циклам делает.

Приходится догадываться что от чего сгенерилось, если бы вы могли просто кусок листинга привести- было бы проще (View->Disassembly Listing в МПЛАБе)

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


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

Да, конечно же.

Вот си:

#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

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


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

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

В данном случае - одинаково (по синтаксису С - одинаково небрежно, корректней "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.

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


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

Тот же код, 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.

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


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

Что-то не получается включить 45-day evaluation HI-TECH C PRO Compiler. Жму "Try HI-TECH C PRO" на вкладке "Driver" окна "Build Options", выбираю первый пункт (45-и дневный пробный период), соглашаюсь с лиц. соглашением, жму "OK" далее соглашаюсь с англ. языком, и жму Финиш. Жму ОК, закрываю МПЛАБ, на запрос о сохранении workspace отвечаю да. Запускаю МПЛАБ и ищу в настройках в окне "Build Options" возможность включения компилятора про версии на пробный период, нигде ничего такого не видно. ЧЯДНТ? Или мож его можно де-то ворованый поставить?

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


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

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

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

Гость
К сожалению, ваш контент содержит запрещённые слова. Пожалуйста, отредактируйте контент, чтобы удалить выделенные ниже слова.
Ответить в этой теме...

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

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

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

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

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

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