avr gcc

Do you have a question? Post it now! No Registration Necessary

Translate This Thread From Russian to

Threaded View
          Очень рад вас видеть, All!

 нарвался при написании примитивной программки на глюк:
 принимаются байты с сом-порта, для контроля передаю байт и его инверсию
 переменную ввел для наглядности, чтоб вопросов о типах небыло

=== Cut ===
  char w1,w2;
  w1=rx[2];
  W2=rx[4];

  if ( ~w1 == w2 )
    {
    out_h=rx[2];
    out_l=rx[3];
    }

 это был исходник, а вот что накомпилялось:

 141:kbm_i.c       ****
 142:kbm_i.c       ****         char w1,w2;
 143:kbm_i.c       ****         w1=rx[2];
 412                .LM50:
 413                .LBB4:
 414 017a 4B81              ldd r20,Y+3
 144:kbm_i.c       ****         w2=rx[4];
 416                .LM51:
 417 017c 8D81              ldd r24,Y+5
 145:kbm_i.c       ****

пока все нормально, в 20 и 24 регистры байты положили из озу

 146:kbm_i.c       ****         if ( ~w1 == w2 )
 419                .LM52:
 420 017e 242F              mov r18,r20
 421 0180 3327              clr r19
 422 0182 2095              com r18
 423 0184 3095              com r19
 424 0186 9927              clr r25
 425 0188 2817              cp r18,r24
 426 018a 3907              cpc r19,r25
 427 018c 31F4              brne .L25

8-ми битную арифментику гцц не любит, и в итоге имеем всегда разные 19 и 25
регистры, и всегда невыполненное условие.

 147:kbm_i.c       ****           {
 148:kbm_i.c       ****           out_h=rx[2];
 429                .LM53:
 430 018e 4093 0000         sts out_h,r20
 149:kbm_i.c       ****           out_l=rx[3];
 432                .LM54:
 433 0192 8C81              ldd r24,Y+4
 434 0194 8093 0000         sts out_l,r24
 435 0198 9ECF              rjmp .L29
 436                .L25:
 150:kbm_i.c       ****           }
=== Cut ===

что делать? или я совсем в С ничего не понимаю? с явным приведением типов
простейшая проверка на равенство байта и инверсии другого байта в такого
монстра превращается... и у меня всеравно не сработало...

два предыдущих проекта в 20к и 25к кода на меге32 счас проверять буду,
их еще полностью в деле не гоняли... правда там с TCP-IP работа у меня,
и чаров почти нет, может поэтому и пронесло.

невезение продожается, 13-я вытащеная из линейки мега8 в дипе прошиваться
не захотела... ни в устройстве, ни отдельно. 14-я прошилась и работает.
все предыдущие тоже работают...


        AVL

Re: avr gcc
Quoted text here. Click to load it

Это у тебя глюк, обусловленный невнимательным чтением книг.

Quoted text here. Click to load it

А чего ты ожидал? Арифметика в Си всегда минимум int, следовательнно
~0x00nn == 0xFFmm которые НИКОГДА не равны 0x00xx или пусть даже 0xFFxx.

Запиши как if ((unsigned char)(~w1) == (unsigned char)w2) и будет тебе
счастье.  И никаких там фокусов после этого быть не должно, ну а если
неэффективно - ну что поделать.


Аркадий

avr gcc
Привет Vasiliy!

19 Sep 04 13:27, Vasiliy Andreev писал All:


 VA>  146:kbm_i.c       ****         if ( ~w1 == w2 )
 VA>  419                .LM52:
 VA>  420 017e 242F              mov r18,r20
 VA>  421 0180 3327              clr r19
 VA>  422 0182 2095              com r18
 VA>  423 0184 3095              com r19
 VA>  424 0186 9927              clr r25
 VA>  425 0188 2817              cp r18,r24
 VA>  426 018a 3907              cpc r19,r25
 VA>  427 018c 31F4              brne .L25

    Покажи все ключи, с которыми звал компилятор. Я уже догадался, что там не
так, но ты покажи сначала. У меня avr-gcc 3.4.0 дает совершенно правильный код.

Всего наилучшего,                                 [Team PCAD 2000]
Алексей М.
... Если долго думать одни и те же мысли, они становятся грязными.

avr gcc
          Очень рад вас видеть, Alex!

20 Сен 04 в 00:18, Alex Mogilnikov писал Vasiliy Andreev следующее:

 AM> Привет Vasiliy!

 AM> 19 Sep 04 13:27, Vasiliy Andreev писал All:


 VA>>  146:kbm_i.c       ****         if ( ~w1 == w2 )
 VA>>  419                .LM52:
 VA>>  420 017e 242F              mov r18,r20
 VA>>  421 0180 3327              clr r19
 VA>>  422 0182 2095              com r18
 VA>>  423 0184 3095              com r19
 VA>>  424 0186 9927              clr r25
 VA>>  425 0188 2817              cp r18,r24
 VA>>  426 018a 3907              cpc r19,r25
 VA>>  427 018c 31F4              brne .L25

 AM>     Покажи все ключи, с которыми звал компилятор. Я уже догадался, что там
 AM> не так, но ты покажи сначала. У меня avr-gcc 3.4.0 дает совершенно
 AM> правильный код.

 меня ткнули носом в необходимость чтения книг, но о 16-ти битности я и
 сам знаю, но до этого с подобным не сталкивался, так как в больше в "райде"
 под х51 и борландах под х86 писал, и на эти грабли не наступал. вот и
 спросил у "мирового разума", как обойти это без явного преобразования типов.

=== Cut ===
# MCU name
MCU = atmega8

# Output format. (can be srec, ihex, binary)
FORMAT = ihex

# Target file name (without extension).
TARGET = kbm_r

# List C source files here. (C dependencies are automatically generated.)
SRC = $(TARGET).c  SERIAL.c

# Optimization level, can be [0, 1, 2, 3, s].
OPT = s

# Compiler flag to set the C Standard level.
# c89   - "ANSI" C
# gnu89 - c89 plus GCC extensions
# c99   - ISO C99 standard (not yet fully implemented)
# gnu99 - c99 plus GCC extensions
CSTANDARD = -std=gnu99

# Place -D or -U options here
CDEFS =

# Place -I options here
CINCS =

# Compiler flags.
#  -g:           generate debugging information
#  -O*:          optimization level
#  -f...:        tuning, see GCC manual and avr-libc documentation
#  -Wall...:     warning level
#  -Wa,...:      tell GCC to pass this to the assembler.
#    -adhlns...: create assembler listing
CFLAGS = -g
CFLAGS += $(CDEFS) $(CINCS)
CFLAGS += -O$(OPT)
CFLAGS += -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums
CFLAGS += -Wall -Wstrict-prototypes
CFLAGS += -Wa,-adhlns=$(<:.c=.lst)
CFLAGS += $(patsubst %,-I%,$(EXTRAINCDIRS))
CFLAGS += $(CSTANDARD)

# Assembler flags.
#  -Wa,...:   tell GCC to pass this to the assembler.
#  -ahlms:    create listing
#  -gstabs:   have the assembler create line number information
ASFLAGS = -Wa,-adhlns=$(<:.S=.lst),-gstabs

#Additional libraries.

# Minimalistic printf version
PRINTF_LIB_MIN = -Wl,-u,vfprintf -lprintf_min

# Floating point printf version (requires MATH_LIB = -lm below)
PRINTF_LIB_FLOAT = -Wl,-u,vfprintf -lprintf_flt

PRINTF_LIB =

# Minimalistic scanf version
SCANF_LIB_MIN = -Wl,-u,vfscanf -lscanf_min

# Floating point + %[ scanf version (requires MATH_LIB = -lm below)
SCANF_LIB_FLOAT = -Wl,-u,vfscanf -lscanf_flt

SCANF_LIB =

MATH_LIB = -lm

EXTMEMOPTS =

# Linker flags.
#  -Wl,...:     tell GCC to pass this to linker.
#    -Map:      create map file
#    --cref:    add cross reference to  map file
LDFLAGS = -Wl,-Map=$(TARGET).map,--cref
LDFLAGS += $(EXTMEMOPTS)
LDFLAGS += $(PRINTF_LIB) $(SCANF_LIB) $(MATH_LIB)

=== Cut ===

        AVL

avr gcc
Привет Vasiliy!

20 Sep 04 09:05, Vasiliy Andreev писал Alex Mogilnikov:

 AM>>     Покажи все ключи, с которыми звал компилятор. Я уже
 AM>> догадался, что там не так, но ты покажи сначала. У меня avr-gcc
 AM>> 3.4.0 дает совершенно правильный код.

 VA> === Cut ===
 VA> CFLAGS += -funsigned-char -funsigned-bitfields -fpack-struct
 VA> === Cut ===

    Я так и думал. Ты сам сказал компилятору считать все char как unsigned
char, после чего пишешь:

    if(~w1 == w2)

    В данном случае компилятор совершенно прав, сгенерив код, в котором условие
никогда не выполняется. По правилам языка C, преобразование unsigned char в int
выполняется дополнением нулями справа. Соответственно, после инвертирования в
старших байтах всегда будут единицы, и ~w1 никогда не может быть равно w2.

 VA>  меня ткнули носом в необходимость чтения книг, но о 16-ти битности я
 VA> и сам знаю, но до этого с подобным не сталкивался, так как в больше в
 VA> "райде" под х51 и борландах под х86 писал, и на эти грабли не
 VA> наступал. вот и спросил у "мирового разума", как обойти это без явного
 VA> преобразования типов.

    Задавай сразу правильные типы - не придется их преобразовывать. В твоем
примере w1 и w2 должны были быть типа signed char.
    А (ИМХО) еще более правильным было бы написать так:

    w1 = ~rx[2];
    w2 = rx[4];
    if(w1 == w2)

Всего наилучшего,                                 [Team PCAD 2000]
Алексей М.
... Крыскас. Потому что крыса вам доверяет.

Re: avr gcc
Hемедленно нажми на RESET, Alex Mogilnikov!


 AM>     А (ИМХО) еще более правильным было бы написать так:

 AM>     w1 = ~rx[2];
 AM>     w2 = rx[4];
 AM>     if(w1 == w2)

  if (w1^0xff == w2) -- имхо, более наглядно.


Site Timeline