|
|
  |
Пара простых вопросов, Но для меня важных |
|
|
|
Oct 24 2006, 19:13
|
Гуру
     
Группа: Свой
Сообщений: 2 712
Регистрация: 28-11-05
Из: Беларусь, Витебск, Строителей 18-4-220
Пользователь №: 11 521

|
Похоже, что компилятор просматривает не отдельные инструкции, а целые фрагменты текста. Об этом говорит вспыхивающие то там то тут топики, про то что изменил порядок следования операндов или ещё что-нибудь не существенное с точки зрения алгоритма, а результирующий код увеличился либо уменьшился весьма существенно. А рекомендаций по данному вопросу нет. Да и как их дашь если это зависит от компилятора и даже от его версии. Тем не менее наверняка каждый выработал для себя такие "оптимальные конструкции". Естественно, что каждый раз не будешь их проверять, но всё же. И вот у меня два вопроса. 1) Имеется переменная 32 бита (X) и 4 байта (b0-b3). Мне необходимо занести значение b0-b3 в X. На первый взгляд напрашивается две конструкции. Хотя может я и не угадал ни разу. а) X=b0; X+=(uint32_t)b1<<8; // Или '|=' X+=(uint32_t)b2<<16; X+=(uint32_t)b3<<24; б) X=b0; X+=b1*0x100; X+=b2*0x10000; X+=b3*0x1000000; 2) Необходимо байт 0 многобитной переменной X занести в байт b. При конструкции b=X; // Компилятор выдаёт предупреждение, но выполняет правильно Если использовать b=X & 0xff; // То компилятор не ругается. А как записать эффективней.
|
|
|
|
|
Oct 25 2006, 06:39
|

Частый гость
 
Группа: Свой
Сообщений: 89
Регистрация: 28-10-05
Из: Киев
Пользователь №: 10 227

|
Цитата(_artem_ @ Oct 25 2006, 06:41)  2) По моему не имеет разницы - код должен быть одинаков. а по-моему. код разный будет: во втором случае добавляется явно прописанная операция (хотя, возможно, она соптимизируется компилятором), в то время как в первом варианте просто перекопируется младший байт... а результат точно одинаковый
|
|
|
|
|
Oct 25 2006, 07:21
|

Знающий
   
Группа: Свой
Сообщений: 697
Регистрация: 26-07-05
Из: Могилев
Пользователь №: 7 095

|
Цитата(SasaVitebsk @ Oct 24 2006, 22:13)  1) Имеется переменная 32 бита (X) и 4 байта (b0-b3). Мне необходимо занести значение b0-b3 в X. На первый взгляд напрашивается две конструкции. Хотя может я и не угадал ни разу. а) X=b0; X+=(uint32_t)b1<<8; // Или '|=' X+=(uint32_t)b2<<16; X+=(uint32_t)b3<<24; б) X=b0; X+=b1*0x100; X+=b2*0x10000; X+=b3*0x1000000; Если переменные (b0-b3) связаны по смыслу, то ИМХО их удобнее собрать в массив , а дальше можно сделать так: Код typedef union{ unsigned char DIM[4]; unsigned long VAR; }multivar;
unsigned long X; multivar Y={1,2,3,4}; ... X=Y.VAR; ... Цитата 2) Необходимо байт 0 многобитной переменной X занести в байт b. При конструкции b=X; // Компилятор выдаёт предупреждение, но выполняет правильно Если использовать b=X & 0xff; // То компилятор не ругается.
А как записать эффективней. Код b=(unsigned char)X;
|
|
|
|
|
Oct 25 2006, 09:18
|
Гуру
     
Группа: Свой
Сообщений: 2 712
Регистрация: 28-11-05
Из: Беларусь, Витебск, Строителей 18-4-220
Пользователь №: 11 521

|
Цитата(_artem_ @ Oct 25 2006, 06:41)  1) X = b3; X = (X<<8) | b2; X = (X<<8) | b1; X = (X<<8) | b0; А в этом случае в результирующем коде случайно не будет сдвигов? Просто хотелось бы получить в результате простых 4 команды mov. Вариант с наложением массива я уже где-то спрашивал, и мне ответили, что он не коректен, так как в зависимости от реализации непонятно как компилятор хранит: младшим или старшим вперёд. Вариант b = (uint8_t)X принимается.
|
|
|
|
|
Oct 25 2006, 17:51
|

Знающий
   
Группа: Свой
Сообщений: 697
Регистрация: 26-07-05
Из: Могилев
Пользователь №: 7 095

|
Цитата(SasaVitebsk @ Oct 25 2006, 12:18)  Вариант с наложением массива я уже где-то спрашивал, и мне ответили, что он не коректен, так как в зависимости от реализации непонятно как компилятор хранит: младшим или старшим вперёд. Не совсем понял:младшим или старшим (байтом) вперёд, в зависимости от реализации ЧЕГО? Если не сложно приведите пример, я, честно говоря, думал, что всегда первым в памяти располагается нулевой элемент массива... Есть еще вариант, в моем примере вместо массива использовать структуру, первым в памяти будет располагаться первый член структуры (по крайней мере в ИАРЕ)...
|
|
|
|
|
Oct 25 2006, 18:12
|
Гуру
     
Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882

|
Цитата(Old1 @ Oct 25 2006, 23:51)  Цитата(SasaVitebsk @ Oct 25 2006, 12:18)  Вариант с наложением массива я уже где-то спрашивал, и мне ответили, что он не коректен, так как в зависимости от реализации непонятно как компилятор хранит: младшим или старшим вперёд.
Не совсем понял:младшим или старшим (байтом) вперёд, в зависимости от реализации ЧЕГО? Если не сложно приведите пример, я, честно говоря, думал, что всегда первым в памяти располагается нулевой элемент массива... Есть еще вариант, в моем примере вместо массива использовать структуру, первым в памяти будет располагаться первый член структуры (по крайней мере в ИАРЕ)... В СИ вроде бы нигде и не определен порядок хранения байтов данных в памяти. Точно также как и данных в структуре. Гарантируется только, что будет соблюден порядок следования членов структуры, но не порядок их размещения в памяти. Тем более когда члены структуры имеют разный тип/размер. Особенно это касается невыровненных структур.
|
|
|
|
|
Oct 25 2006, 18:25
|

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095

|
Цитата(SasaVitebsk @ Oct 24 2006, 22:13)  1) Имеется переменная 32 бита (X) и 4 байта (b0-b3). Мне необходимо занести значение b0-b3 в X. На первый взгляд напрашивается две конструкции.
А как записать эффективней. Первый вариант прекрасно компилируется в четыре mov. Второй без оптимизации может вызвать подтягивание библиотечной функции умножения. Использование "+" или " | " по моим наблюдениям на результат не влияли. 10 лет назад влияли, " | " было предпочтительней. По второму вопросу уже ответили. А что мешает посмотреть листинг?
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Oct 25 2006, 21:54
|
Гуру
     
Группа: Свой
Сообщений: 2 712
Регистрация: 28-11-05
Из: Беларусь, Витебск, Строителей 18-4-220
Пользователь №: 11 521

|
Цитата(Сергей Борщ @ Oct 25 2006, 21:25)  А что мешает посмотреть листинг? Пожалуйста не думайте, что я неуважаю Ваше личное время. Учитывая, что я начинающий на Си я просматриваю листинг. Правда всё время это делать не будешь. А задаю вопрос потому что ... Цитата(Сергей Борщ @ Oct 25 2006, 21:25)  10 лет назад влияли, " | " было предпочтительней. У вас накоплен большой опыт применения тех или иных конструкций. И, просто хочу им воспользоваться. Чтобы при переходе с версии на версию, с камня на камень, не вглядываться постоянно в этот листинг. Цитата( @ Oct 25 2006, 21:25)  #define LBYTE(w) (*((byte*)&w)) #define HBYTE(w) (*(((byte*)&w)+1)) #define L2BYTE(w) (*(((byte*)&w)+2)) #define H2BYTE(w) (*(((byte*)&w)+3))
LBYTE(X) = b0; HBYTE(X) = b1; L2BYTE(X) = b2; H2BYTE(X) = b3; До этого не додумался. Спасибо всем ответившим. И ещё один вопрос. Имеется структура с битовыми полями к примеру. __no_init struct { uint8_t RXOFF : 1, //Буфер переполнен, загрузка приостановлена RMaster : 1,// Контроллер в режиме "Мастер" RLoadActKom : 1,/ Разрешена Загрузка команд в "активную зону" Color : 3, // цвет } Flag; У меня почему-то не работает такая конструкция (компилятор не ругается) Flag.Color=7; Flag.Color--; Что я делаю не так.
|
|
|
|
|
Oct 26 2006, 06:21
|

Шаман
     
Группа: Модераторы
Сообщений: 3 064
Регистрация: 30-06-04
Из: Киев, Украина
Пользователь №: 221

|
Цитата(SasaVitebsk @ Oct 26 2006, 00:54)  Имеется структура с битовыми полями к примеру. __no_init struct { uint8_t RXOFF : 1, //Буфер переполнен, загрузка приостановлена RMaster : 1,// Контроллер в режиме "Мастер" RLoadActKom : 1,/ Разрешена Загрузка команд в "активную зону" Color : 3, // цвет } Flag;
У меня почему-то не работает такая конструкция (компилятор не ругается) Flag.Color=7; Flag.Color--;
Что я делаю не так. Что значит "не работает"? Я только что проверил, всё отлично работает. Разве что после Color : 3 надо не запятую писать, а точку с запятой.
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|