|
Перенос кода из под ИАРа на WinAVR, возникают некоторые вопросы... |
|
|
|
 |
Ответов
|
Nov 27 2008, 17:18
|
Знающий
   
Группа: Участник
Сообщений: 596
Регистрация: 26-05-06
Из: Москва
Пользователь №: 17 484

|
Цитата(sonycman @ Nov 27 2008, 20:03)  2aesok Если у меня в программе операнд имеет тип char, то это значит, что ни при каких условиях не будет достигнуто переполнение. Я вам привел пример когда оба операнда имеют тип char, и происходит переполнение. Цитата(sonycman @ Nov 27 2008, 20:03)  Следуя вашей логике, можно и операнды типа word обрабатывать, расширяя до double word... Компилятор это за вас не сделает, но если Вы не хотите получит ошибку переполнения, то Вы проанализируете исходные данные и формулы, и возжможно, да будете выполнять промежуточные расчеты с 32-битными числами, даже если операнды и результат 16-битные. Анатолий. Цитата(Rst7 @ Nov 27 2008, 20:08)  Только не надо спрашивать, как это - "в другом стиле", на форуме выложенно достаточно, чтобы оценить кривость моих рук  Компилятор тоже не может этого оценить. Но он стараеться генерировать правильный код в не зависимости от кривости рук програмиста, при этом код иногда получаеться более длинным. Анатолий.
|
|
|
|
|
Nov 27 2008, 19:49
|
Знающий
   
Группа: Участник
Сообщений: 596
Регистрация: 26-05-06
Из: Москва
Пользователь №: 17 484

|
Цитата Этот пример не имеет ничего общего с моим приложением. Как не трудно было заметить из моего примера, константа LCD_WIDTH всегда складывается с отрицательным числом. Плюс операнды имеют значения, не допускающие переполнения. Это Ваш пример? Код #define LCD_WIDTH 96 byte lcdGetStringWidth(PGM_P text);
void lcdPrintText(PGM_P text, byte flags, signed char x, signed char y) switch(flags & 0xe0) { case TXT_CENTERED: if (x < 0) { x = (LCD_WIDTH + x - lcdGetStringWidth(text)) / 2; } (LCD_WIDTH + x - lcdGetStringWidth(text)) = 96 + [-128..-1] - [0..255] = [95..-287] Это чисто попещаеться в signed char? В unsigned char? Цитата Насчёт кривости рук - что вы скажете про то, откуда берутся странные предупреждения об обязательной инициализации и так инициализированных строковых массивов, расположенных в памяти программ? Исходники GCC находяться здесь http://gcc.gnu.org/viewcvs/ Вы можете убрать мешающие Вам предупреждения сами. Анатолий.
Сообщение отредактировал aesok - Nov 27 2008, 19:54
|
|
|
|
|
Nov 27 2008, 21:52
|

Любитель
    
Группа: Свой
Сообщений: 1 864
Регистрация: 20-08-06
Из: Тольятти
Пользователь №: 19 695

|
Цитата(aesok @ Nov 27 2008, 23:49)  Это Ваш пример? Код #define LCD_WIDTH 96 byte lcdGetStringWidth(PGM_P text);
void lcdPrintText(PGM_P text, byte flags, signed char x, signed char y) switch(flags & 0xe0) { case TXT_CENTERED: if (x < 0) { x = (LCD_WIDTH + x - lcdGetStringWidth(text)) / 2; } (LCD_WIDTH + x - lcdGetStringWidth(text)) = 96 + [-128..-1] - [0..255] = [95..-287] Это чисто попещаеться в signed char? В unsigned char? Нет. Но такие величины никогда не будут получены, так как операнды имеют значения, не допускающие переполнения. Не надо выдёргивать из контекста. Цитата Исходники GCC находяться здесь http://gcc.gnu.org/viewcvs/ Вы можете убрать мешающие Вам предупреждения сами. Как? Я, у которого в программе переполнения на каждом шагу, должен исправлять глюки "умного" компилятора, который стараеться генерировать правильный код в не зависимости от кривости рук програмиста? Что-то мне кажется, что мы ведём непродуктивный диалог. После того, как было установлено, что приведение операндов к 16-ти битам делается для того, чтобы просто удовлетворять стандарту, вы хотите сказать, что это не так? Что на самом деле этот шаг направлен на предотвращение переполнения? Цитата(alx2 @ Nov 27 2008, 15:29)  Как ты получил такой код??? =8-( ) Вот такой тестовый пример: Код int do_something(void);
void fff(char flags) { switch(flags & 0xe0) { case 0x80: do_something(); } } у меня компилируется вот в такой код: Код fff: /* prologue: function */ /* frame size = 0 */ andi r24,lo8(-32) cpi r24,lo8(-128) brne .L4 rcall do_something .L4: ret при любой -O отличной от -O0. gcc-4.3.1. Скажи, пожалуйста, версию своего компилятора, с какой оптимизацией компилировался код и как определено byte. Добрался до компа. На всякий случай повторю повнятнее: У меня WinAVR 20081118rc2 с компилятором GCC 4.3.2. Оптимизация Os плюс ещё несколько "фишек". Командная строка компилятора: Код avr-g++ -I"F:\Electronics\Projects\GNU\FanController\Headers" -Wall -g2 -gdwarf-2 -Os -fpack-struct -fshort-enums -mcall-prologues -funsigned-char -funsigned-bitfields -fno-exceptions -fno-threadsafe-statics -fno-inline-small-functions -ffunction-sections -mmcu=atmega88 -DF_CPU=10000000UL -MMD -MP -MF"Sources/main.d" -MT"Sources/main.d" -c -o"Sources/main.o" "../Sources/main.cpp" Скомпилировал твой пример, вот что получилось: Код void do_something(char b) { volatile static char a = b; }
void fff(char flags) { switch(flags & 0xe0) { case 0x80: do_something(0); case 0xc0: do_something(1); } }
int main( void ) {
fff(128); ... и листинг: Код void fff(char flags) { switch(flags & 0xe0) 15be: 90 e0 ldi r25, 0x00; 0 15c0: 80 7e andi r24, 0xE0; 224 15c2: 90 70 andi r25, 0x00; 0 15c4: 80 38 cpi r24, 0x80; 128 15c6: 91 05 cpc r25, r1 15c8: 21 f0 breq .+8 ; 0x15d2 <fff(char)+0x14> 15ca: 80 3c cpi r24, 0xC0; 192 15cc: 91 05 cpc r25, r1 15ce: 29 f4 brne .+10 ; 0x15da <fff(char)+0x1c> 15d0: 02 c0 rjmp .+4 ; 0x15d6 <fff(char)+0x18> { case 0x80: do_something(0); 15d2: 80 e0 ldi r24, 0x00; 0 15d4: e9 df rcall .-46 ; 0x15a8 <do_something(char)> case 0xc0: do_something(1); 15d6: 81 e0 ldi r24, 0x01; 1 15d8: e7 df rcall .-50 ; 0x15a8 <do_something(char)> 15da: 08 95 ret
|
|
|
|
|
Nov 27 2008, 22:22
|
Знающий
   
Группа: Участник
Сообщений: 596
Регистрация: 26-05-06
Из: Москва
Пользователь №: 17 484

|
Цитата(sonycman @ Nov 28 2008, 00:52)  Нет. Но такие величины никогда не будут получены, так как операнды имеют значения, не допускающие переполнения. Не надо выдёргивать из контекста. Причем тут я? Я человек я мог бы Вас и понять. Я Вам показываю как думает тупая железка, тоесть компилятор. Где Вы ему сказали что " операнды имеют значения, не допускающие переполнения"? Я Вам показывал вариант как это ему сказать: x = ( byte) (LCD_WIDTH + x - lcdGetStringWidth(text)) / 2; И компилятор начал вычислять выражение как 8-битное. Цитата(sonycman @ Nov 28 2008, 00:52)  Как? Я, у которого в программе переполнения на каждом шагу, должен исправлять глюки "умного" компилятора, который стараеться генерировать правильный код в не зависимости от кривости рук програмиста?  Я не говорил что у Вас кривые руки, Я говорил что компилятор должен компилировать программу написанную даже кривыми руками, при этом программа должна работать в соответствии со стандартом, а в стандарте никаких указазий о скорости выполнения программы нет. Это оставленно на осмотрение разработчика компилятора. Цитата(sonycman @ Nov 28 2008, 00:52)  После того, как было установлено, что приведение операндов к 16-ти битам делается для того, чтобы просто удовлетворять стандарту, вы хотите сказать, что это не так? Что на самом деле этот шаг направлен на предотвращение переполнения? Я попытался на примере Вам показать почему так написан стандарт. Цитата(sonycman @ Nov 28 2008, 00:52)  Добрался до компа. На всякий случай повторю повнятнее: Пока не знаю. Анатолий.
Сообщение отредактировал aesok - Nov 27 2008, 22:28
|
|
|
|
|
Nov 27 2008, 22:46
|

Любитель
    
Группа: Свой
Сообщений: 1 864
Регистрация: 20-08-06
Из: Тольятти
Пользователь №: 19 695

|
Цитата(aesok @ Nov 28 2008, 02:22)  Я попытался на примере Вам показать почему так написан стандарт. Анатолий. Хм... то есть, разработчики стандарта таким образом подстраховали все вычисления с операндами типа char? Мне всё равно трудно понять рациональность этого хода. Потому, что ошибка с переполнением может возникнуть с любым по размеру операндом: 8, 16, 32, 64 и так далее бит. Почему для 8-ми бит сделали исключение? Цитата (LCD_WIDTH + x - lcdGetStringWidth(text)) = 96 + [-128..-1] - [0..255] = [95..-287] Зачем "правильно" считать результат на 16-ти битах, если в конце концов он будет разрушен, будучи "обрезанным" и "запиханным" в signed char? Если программист не продумал все варианты - ошибка обязательно вылезет всё равно. Да... Но всё-же, спасибо за попытку всё объяснить. Извиняюсь за некоторое раздражение в моём тоне. В любом случае, стандарты придумывают весьма умные дядьки, не чета таким, как я Порой трудно бывает понять их мотивы. Воистину, пути их неисповедимы
|
|
|
|
|
Nov 27 2008, 23:20
|
Знающий
   
Группа: Участник
Сообщений: 596
Регистрация: 26-05-06
Из: Москва
Пользователь №: 17 484

|
Цитата(sonycman @ Nov 28 2008, 01:46)  Хм... то есть, разработчики стандарта таким образом подстраховали все вычисления с операндами типа char? Мне всё равно трудно понять рациональность этого хода. Потому, что ошибка с переполнением может возникнуть с любым по размеру операндом: 8, 16, 32, 64 и так далее бит. Почему для 8-ми бит сделали исключение? На самом деле исключение сделано для int. Это как бы тип по умолчанию, разрядность int обычно равна разрядности регистров общего назначения, что гарантирует максимальную производительность для этого типа. Для AVR разрядность int больше разрядности регистра. Сделать int 8-битным нельзя, в стандарте требуется - размерность указателя равна размерности int, а 8-битный указатель это слишком мало. Если быть совсем точным то avr-gcc имеет ключ: -mint8 Use an 8-bit 'int' type Его практическая ценность его мала, avr-libc не совместима с этим ключом, и никогда не будет. Но если будете писать что нибудь маленькое, можете с ним поиграться. Цитата Зачем "правильно" считать результат на 16-ти битах, если в конце концов он будет разрушен, будучи "обрезанным" и "запиханным" в signed char? Если программист не продумал все варианты - ошибка обязательно вылезет всё равно. Потому что в вашем примере обрезание рузультата до char произойдеи уже после деления, а для того чтобы результат деления на 2 влез в char делимое может иметь значение до char * 2, и для его хранения нужен int. Цитата Порой трудно бывает понять их мотивы. Воистину, пути их неисповедимы На самом деле все очень просто, отладив несколько своих проектов Вы начнете думать как они... Анатолий.
Сообщение отредактировал aesok - Nov 27 2008, 23:26
|
|
|
|
Сообщений в этой теме
sonycman Перенос кода из под ИАРа на WinAVR Nov 22 2008, 19:39 demiurg_spb Поможет WinAVR\avr\include\util... Nov 22 2008, 20:04 sonycman Цитата(demiurg_spb @ Nov 23 2008, 00:04) ... Nov 22 2008, 21:17  ReAl Цитата(sonycman @ Nov 22 2008, 23:17) Раз... Nov 23 2008, 18:03   sonycman Цитата(ARV @ Nov 23 2008, 21:23) как прав... Nov 23 2008, 19:09    ReAl Цитата(sonycman @ Nov 23 2008, 21:09) то ... Nov 23 2008, 21:37    Сергей Борщ Цитата(sonycman @ Nov 23 2008, 21:09) то ... Nov 23 2008, 21:45   Petka Цитата(ReAl @ Nov 23 2008, 21:03) У gcc е... Nov 23 2008, 20:38    sonycman Цитата(Petka @ Nov 24 2008, 00:38) В прин... Nov 23 2008, 21:37     ReAl Цитата(sonycman @ Nov 23 2008, 23:37) А е... Nov 23 2008, 21:51    ReAl Цитата(Petka @ Nov 23 2008, 22:38) В прин... Nov 23 2008, 21:43     Petka Цитата(ReAl @ Nov 24 2008, 00:43) Это НЕ ... Nov 24 2008, 07:35 MrYuran Насколько я помню, у WinAVR имеется отличная докум... Nov 23 2008, 08:24 sonycman Цитата(MrYuran @ Nov 23 2008, 12:24) Наск... Nov 23 2008, 14:33 sonycman Цитата(MrYuran @ Nov 23 2008, 12:24) Наск... Nov 23 2008, 17:09  ARV Цитата(sonycman @ Nov 23 2008, 20:09) А м... Nov 23 2008, 17:23  alx2 Цитата(sonycman @ Nov 23 2008, 22:09) А м... Nov 23 2008, 21:54 sonycman Портировал я свою программу с IARа на GCC.
Оптимиз... Nov 24 2008, 11:05 aesok Цитата(sonycman @ Nov 24 2008, 14:05) Так... Nov 24 2008, 11:35  sonycman Цитата(aesok @ Nov 24 2008, 15:35) Добавт... Nov 24 2008, 11:57   aesok Цитата(sonycman @ Nov 24 2008, 14:57) У м... Nov 24 2008, 19:07    sonycman Цитата(ARV @ Nov 24 2008, 20:40) смутил к... Nov 24 2008, 19:26     ARV Цитата(sonycman @ Nov 24 2008, 22:26) Поп... Nov 24 2008, 20:00      sonycman Цитата(ARV @ Nov 25 2008, 00:00) Кодavr-g... Nov 24 2008, 20:23       Сергей Борщ Цитата(sonycman @ Nov 24 2008, 22:23) Вот... Nov 24 2008, 21:14        sonycman Цитата(Сергей Борщ @ Nov 25 2008, 01:14) ... Nov 24 2008, 23:36         gotty Цитата(sonycman @ Nov 25 2008, 01:36) Так... Nov 25 2008, 07:39 demiurg_spb Цитата(sonycman @ Nov 24 2008, 14:05) и в... Nov 24 2008, 11:56 alx2 Привет, sonycman!
Цитата(sonycman @ Nov 2... Nov 25 2008, 21:58  Rst7 Цитата(alx2 @ Nov 25 2008, 23:58) И зря. ... Nov 26 2008, 12:46 sonycman Интересно, почему при делении на два не всегда исп... Nov 24 2008, 14:15 MrYuran Цитата(sonycman @ Nov 24 2008, 17:15) Инт... Nov 24 2008, 14:22  sonycman Цитата(MrYuran @ Nov 24 2008, 18:22) Я об... Nov 24 2008, 14:46   demiurg_spb Цитата(sonycman @ Nov 24 2008, 17:46) Ещё... Nov 24 2008, 15:58    sonycman Цитата(demiurg_spb @ Nov 24 2008, 19:58) ... Nov 24 2008, 16:05 ARV смутил ключик --gc-sections я всегда использую -Wl... Nov 24 2008, 16:40 ARV -ff-sections заставляет компилятор размещать код к... Nov 25 2008, 05:56 sonycman Цитата(gotty @ Nov 25 2008, 11:39) Для то... Nov 25 2008, 09:41  ARV Цитата(sonycman @ Nov 25 2008, 12:41) Над... Nov 25 2008, 09:52  gotty Цитата(sonycman @ Nov 25 2008, 11:41) Лин... Nov 25 2008, 10:01   sonycman Цитата(ARV @ Nov 25 2008, 13:52) практика... Nov 25 2008, 10:42    ARV Цитата(sonycman @ Nov 25 2008, 13:42) Пон... Nov 26 2008, 07:22     aesok Цитата(ARV @ Nov 26 2008, 10:22) на сколь... Nov 26 2008, 09:39      ARV Цитата(aesok @ Nov 26 2008, 12:39) На как... Nov 26 2008, 09:50 sonycman Цитата(alx2 @ Nov 26 2008, 01:58) Привет,... Nov 26 2008, 10:17 alx2 Цитата(sonycman @ Nov 26 2008, 15:17) Сей... Nov 26 2008, 20:20  Rst7 Цитата(alx2 @ Nov 26 2008, 22:20) -2, -3
... Nov 26 2008, 20:45   alx2 Цитата(Rst7 @ Nov 27 2008, 01:45) Если уж... Nov 26 2008, 21:35    Rst7 Цитата(alx2 @ Nov 26 2008, 23:35) оно дае... Nov 26 2008, 21:56   sonycman Цитата(Rst7 @ Nov 27 2008, 00:45) Однако,... Nov 26 2008, 22:02    aesok Цитата(sonycman @ Nov 27 2008, 01:02) Но ... Nov 27 2008, 04:14     alx2 Цитата(aesok @ Nov 27 2008, 09:14) The co... Nov 27 2008, 11:50    Rst7 Цитата(sonycman @ Nov 27 2008, 00:02) А д... Nov 27 2008, 07:56     gotty Цитата(Rst7 @ Nov 27 2008, 09:56) Аналоги... Nov 27 2008, 08:51      Rst7 Цитата(gotty @ Nov 27 2008, 10:51) Это на... Nov 27 2008, 09:08       gotty Цитата(Rst7 @ Nov 27 2008, 11:08) Ссылку.... Nov 27 2008, 09:24      sonycman Цитата(gotty @ Nov 27 2008, 12:51) Это на... Nov 27 2008, 09:28       zltigo Цитата(sonycman @ Nov 27 2008, 12:28) Но ... Nov 27 2008, 09:45        sonycman Цитата(zltigo @ Nov 27 2008, 13:45) Следо... Nov 27 2008, 10:04         Сергей Борщ Цитата(sonycman @ Nov 27 2008, 12:04) Пон... Nov 27 2008, 11:35     aesok Цитата(Rst7 @ Nov 27 2008, 10:56) вычисля... Nov 27 2008, 16:52      Rst7 Цитата(aesok @ Nov 27 2008, 18:52) Расмот... Nov 27 2008, 17:08    alx2 Цитата(sonycman @ Nov 27 2008, 03:02) Код... Nov 27 2008, 11:29     sonycman Цитата(alx2 @ Nov 27 2008, 15:29) Как ты ... Nov 27 2008, 13:35        sonycman Цитата(aesok @ Nov 28 2008, 03:20) Потому... Nov 28 2008, 00:34     alx2 Цитата(sonycman @ Nov 28 2008, 02:52) Код... Nov 29 2008, 11:51      sonycman Цитата(alx2 @ Nov 29 2008, 15:51) Поэтому... Nov 29 2008, 21:02       aesok Цитата(sonycman @ Nov 30 2008, 00:02) Я п... Nov 29 2008, 22:00        sonycman Цитата(aesok @ Nov 30 2008, 02:00) Не заб... Nov 29 2008, 22:24         alx2 Цитата(sonycman @ Nov 30 2008, 03:24) А в... Nov 30 2008, 14:40        Rst7 Цитата(aesok @ Nov 30 2008, 00:00) меня н... Nov 29 2008, 22:24         aesok Цитата(Rst7 @ Nov 30 2008, 01:24) Простит... Nov 29 2008, 22:36       alx2 Цитата(sonycman @ Nov 30 2008, 02:02) Зач... Nov 30 2008, 13:41        sonycman Цитата(Rst7 @ Nov 30 2008, 17:46) Жесть. ... Nov 30 2008, 14:19 Сергей Борщ Цитата(sonycman @ Nov 28 2008, 02:34) То ... Nov 28 2008, 01:08 Rst7 ЦитатаВо-вторых, я подозреваю, что вероятность вых... Nov 29 2008, 12:53 AHTOXA Цитата(Rst7 @ Nov 29 2008, 17:53) А значи... Nov 29 2008, 19:31  Rst7 Цитата(AHTOXA @ Nov 29 2008, 21:31) Но ве... Nov 29 2008, 21:43   sonycman Цитата(Rst7 @ Nov 30 2008, 01:43) С друго... Nov 29 2008, 21:56    Rst7 Цитата(sonycman @ Nov 29 2008, 23:56) Там... Nov 29 2008, 22:53     sonycman Цитата(Rst7 @ Nov 30 2008, 02:53) Дык где... Nov 29 2008, 23:14      alx2 Цитата(sonycman @ Nov 30 2008, 04:14) В И... Nov 30 2008, 14:21       sonycman Цитата(alx2 @ Nov 30 2008, 18:21) Можно в... Nov 30 2008, 14:34     aesok Цитата(Rst7 @ Nov 30 2008, 01:53) Вынужде... Nov 29 2008, 23:31    alx2 Цитата(sonycman @ Nov 30 2008, 02:56) Име... Nov 30 2008, 13:57   AHTOXA Цитата(Rst7 @ Nov 30 2008, 02:43) Плохо В... Nov 29 2008, 23:23 alx2 Привет, Rst7!
Цитата(Rst7 @ Nov 29 2008, ... Nov 30 2008, 13:13 sonycman Неважнецки получается у GCC работа со структурой в... Nov 30 2008, 10:23 Rst7 Хоть я и откланялся, но господину sonycman'у о... Nov 30 2008, 11:09 sonycman Цитата(Rst7 @ Nov 30 2008, 15:09) 218 byt... Nov 30 2008, 11:57 sonycman RST7
Не получается у меня научить гнуса правильно ... Nov 30 2008, 13:22 Rst7 Цитатаи результат компиляции первой строчки:
Жест... Nov 30 2008, 13:46
2 страниц
1 2 >
2 чел. читают эту тему (гостей: 2, скрытых пользователей: 0)
Пользователей: 0
|
|
|