Выравнивание! Или как лучше это сделать?!
От: Tarhall Россия  
Дата: 30.03.04 20:46
Оценка:
Есть структура:

typedef struct _HARDWARE_CONT_02{
BYTE command; // Код команды посылки
unsigned lamp :1; // Лампочка
unsigned zero_02_08 :7; // Резерв 0

_HARDWARE_CONT_02() { command=0x22; zero_02_08=0; };
} H_CONT_02, *LPH_CONT_02;

Очень хочется, что бы эта структура занимала 2 байта, а не
получается? Можно ли это сделать и если нельзя, то как более
удобно осушествлять доступ к значениям битов, если учесть, что
эта стуктура тривиальная, а их еще 16 и далеко не все переменные
однобитовые.
Re: Выравнивание! Или как лучше это сделать?!
От: valytch Беларусь  
Дата: 30.03.04 23:37
Оценка:
Здравствуйте, Tarhall, Вы писали:

T>Есть структура:


T>typedef struct _HARDWARE_CONT_02{

T> BYTE command; // Код команды посылки
T> unsigned lamp :1; // Лампочка
T> unsigned zero_02_08 :7; // Резерв 0
T> _HARDWARE_CONT_02() { command=0x22; zero_02_08=0; };
T>} H_CONT_02, *LPH_CONT_02;
T>Очень хочется, что бы эта структура занимала 2 байта, а не
T>получается? Можно ли это сделать и если нельзя, то как более
T>удобно осушествлять доступ к значениям битов, если учесть, что
T>эта стуктура тривиальная, а их еще 16 и далеко не все переменные
T>однобитовые.

Не... Два байта она занимать не будет в любом случае — минимальная
адрессуемая еденица информации — байт, но никак не бит.
А доступ — макрос вида:

Например:

// x - переменная, в которой надо протестить бит (любой целочисленный тип)
// y - номер бита (с нуля) (строго char)
// я - переменная, куда помещать результат ( строго char)
#define get_bit(x, y, z)  __asm xor   edx, edx  \
                          __asm movzx eax, x    \
                          __asm bt    eax, y    \
                          __asm adc   dl,  0x00 \
                          __asm mov   byte ptr [z], dl


Заюзать это можно так:
int a = 0x0a; // (0000.1010)
int b = 0;

get_bit(a, 1, b); 
// имеем в b еденницу
... << RSDN@Home 1.1.3 stable >>
Re[2]: Выравнивание! Или как лучше это сделать?!
От: MaximE Великобритания  
Дата: 31.03.04 01:08
Оценка: 3 (1)
valytch wrote:

> Не... Два байта она занимать не будет в любом случае — минимальная

> адрессуемая еденица информации — байт, но никак не бит.

Предожение как-то противоречит само себе.

> А доступ — макрос вида:

>
>
> // x - переменная, в которой надо протестить бит (любой целочисленный тип)
> // y - номер бита (с нуля) (строго char)
> // я - переменная, куда помещать результат ( строго char)
> #define get_bit(x, y, z)  __asm xor   edx, edx  \
>                           __asm movzx eax, x    \
>                           __asm bt    eax, y    \
>                           __asm adc   dl,  0x00 \
>                           __asm mov   byte ptr [z], dl
>

>
> Заюзать это можно так:
>
> int a = 0x0a; // (0000.1010)
> int b = 0;
>
> get_bit(a, 1, b);
> // имеем в b еденницу
>


Макрос не работает с любым целочисленным типом, например с long long, абсолютно не типобезопасен, допускает любые числа как номер бита, и, что удивительно, не работает на PowerPC.

Альтернатива:

template<unsigned bit, class T>
inline
bool bit_test(T const& t)
{
     typedef char bit_argument_is_illegal[sizeof(T) * 8 > bit];
     return (t & T(1) << bit) != 0;
}

//usage
bool b1 = bit_test<0>(1);
bool b2 = bit_test<63>(0xaa55aa55aa55aa55);
//bool b3 = bit_test<64>(0xaa55aa55aa55aa55);


--
Maxim Egorushkin
MetaCommunications Engineering
http://www.meta-comm.com/engineering/
Posted via RSDN NNTP Server 1.8 beta
Re: Выравнивание! Или как лучше это сделать?!
От: MaximE Великобритания  
Дата: 31.03.04 01:14
Оценка:
Tarhall wrote:

> Есть структура:

>
> typedef struct _HARDWARE_CONT_02{
> BYTE command; // Код команды посылки
> unsigned lamp :1; // Лампочка
> unsigned zero_02_08 :7; // Резерв 0
>
> _HARDWARE_CONT_02() { command=0x22; zero_02_08=0; };
> } H_CONT_02, *LPH_CONT_02;
>
> Очень хочется, что бы эта структура занимала 2 байта, а не
> получается?

Можно:

typedef struct _HARDWARE_CONT_02{
BYTE command; // Код команды посылки
BYTE lamp :1; // Лампочка
BYTE zero_02_08 :7; // Резерв 0

_HARDWARE_CONT_02() { command=0x22; zero_02_08=0; };
} H_CONT_02, *LPH_CONT_02;


--
Maxim Egorushkin
MetaCommunications Engineering
http://www.meta-comm.com/engineering/
Posted via RSDN NNTP Server 1.8 beta
Re[3]: Выравнивание! Или как лучше это сделать?!
От: Шахтер Интернет  
Дата: 31.03.04 01:37
Оценка:
Здравствуйте, MaximE, Вы писали:

ME>Макрос не работает с любым целочисленным типом, например с long long, абсолютно не типобезопасен, допускает любые числа как номер бита, и, что удивительно, не работает на PowerPC.


LOL
... << RSDN@Home 1.1.0 stable >>
В XXI век с CCore.
Копай Нео, копай -- летать научишься. © Matrix. Парадоксы
Re[3]: Выравнивание! Или как лучше это сделать?!
От: valytch Беларусь  
Дата: 31.03.04 18:03
Оценка:
Здравствуйте, MaximE, Вы писали:

ME>valytch wrote:


>> Не... Два байта она занимать не будет в любом случае — минимальная

>> адрессуемая еденица информации — байт, но никак не бит.
ME>Предожение как-то противоречит само себе.

В чём же противоречие? Бит адресовать нельзя! Когда ты в структуре объявляеш
поле в n-бит, в памяти оно будет занимать ЦЕЛОЕ число байт... Так ясно?

>> А доступ — макрос вида:

>>
>>
>> // x - переменная, в которой надо протестить бит (любой целочисленный тип)
>> // y - номер бита (с нуля) (строго char)
>> // я - переменная, куда помещать результат ( строго char)
>> #define get_bit(x, y, z)  __asm xor   edx, edx  \
>>                           __asm movzx eax, x    \
>>                           __asm bt    eax, y    \
>>                           __asm adc   dl,  0x00 \
>>                           __asm mov   byte ptr [z], dl
>>

>>
>> Заюзать это можно так:
>>
>> int a = 0x0a; // (0000.1010)
>> int b = 0;
>>
>> get_bit(a, 1, b);
>> // имеем в b еденницу
>>


ME>Макрос не работает с любым целочисленным типом, например с long long, абсолютно не типобезопасен, допускает любые числа как номер бита, и, что удивительно, не работает на PowerPC.


ME>Альтернатива:


ME>[c]

ME>template<unsigned bit, class T>
ME>inline
ME>bool bit_test(T const& t)
ME>{
ME> typedef char bit_argument_is_illegal[sizeof(T) * 8 > bit];
ME> return (t & T(1) << bit) != 0;
ME>}

Согласен, так ^^^^ оно конечно лучше, но!

Начнём с того, что в вопросе нигде о PowerPC не было
сказано ни слова, ровно как и о платформонезависимости...
Поверь на слово, на x86 он работает замечательно...

Хотя, согласен, форум-то по c++, но такая уж у меня привычка
с детства — зачем писать на с то, что можно написать на паре-тройке
ассемблерных комманд? А типобезопасность... Для такой элементарной
операции не вижу в этом никакого смысла... Хотя, это моё личное мнение...

Согласись, на вопрос я же всё таки ответил?
... << RSDN@Home 1.1.3 stable >>
Re[4]: Выравнивание! Или как лучше это сделать?!
От: MaximE Великобритания  
Дата: 01.04.04 05:03
Оценка: +1
valytch wrote:

> Начнём с того, что в вопросе нигде о PowerPC не было

> сказано ни слова, ровно как и о платформонезависимости...

В вопросе также не было ни слова про x86.

> Поверь на слово, на x86 он работает замечательно...


Верю.

> Хотя, согласен, форум-то по c++, но такая уж у меня привычка

> с детства — зачем писать на с то, что можно написать на паре-тройке
> ассемблерных комманд?

Сомневаюсь в полезности такой привычки — с компилятором (VC 7.1, /O2 /G7) соперничать в генерации кода — неблагодарное занятие:

#define get_bit(x, y, z)  __asm xor   edx, edx  \
                           __asm movzx eax, x    \
                           __asm bt    eax, y    \
                           __asm adc   dl,  0x00 \
                           __asm mov   byte ptr [z], dl


int foo(int x)
{
00401050  push        ecx
     int z(0);
00401051  mov         dword ptr [esp],0
     get_bit(x, 15, z);
00401058  xor         edx,edx
0040105A  movzx       eax,byte ptr [esp+8]
0040105F  bt          eax,0Fh
00401063  adc         dl,0
00401066  mov         byte ptr [esp],dl
     return z;
00401069  mov         eax,dword ptr [esp]
}
0040106C  pop         ecx
0040106D  ret

template<unsigned bit, class T>
inline
bool bit_test(T const& t)
{
      typedef char bit_argument_is_illegal[sizeof(T) * 8 > bit];
      return (t & T(1) << bit) != 0;
}

int bar(int x)
{
     return bit_test<15>(x);
00401070  mov         eax,dword ptr [esp+4]
00401074  shr         eax,0Fh
00401077  and         eax,1


> А типобезопасность... Для такой элементарной

> операции не вижу в этом никакого смысла... Хотя, это моё личное мнение...

Да, смысла почти никакого, кроме:

void f()
{
     class some {};
     some s;
     int z;
     get_bit(s, 15, z);
}


— компилится на 'ура'.

> Согласись, на вопрос я же всё таки ответил?


Соглашусь.

--
Maxim Egorushkin
MetaCommunications Engineering
http://www.meta-comm.com/engineering/
Posted via RSDN NNTP Server 1.8 beta
Re[5]: Выравнивание! Или как лучше это сделать?!
От: valytch Беларусь  
Дата: 01.04.04 15:30
Оценка:
Здравствуйте, MaximE, Вы писали:

ME>valytch wrote:

>> Начнём с того, что в вопросе нигде о PowerPC не было
>> сказано ни слова, ровно как и о платформонезависимости...
ME>В вопросе также не было ни слова про x86.
>> Поверь на слово, на x86 он работает замечательно...
ME>Верю.
>> Хотя, согласен, форум-то по c++, но такая уж у меня привычка
>> с детства — зачем писать на с то, что можно написать на паре-тройке
>> ассемблерных комманд?
ME>Сомневаюсь в полезности такой привычки — с компилятором (VC 7.1, /O2 /G7) соперничать в генерации кода — неблагодарное занятие:

[утеряно]

Убедительно...

>> Согласись, на вопрос я же всё таки ответил?

ME>Соглашусь.

Ну и я соглашусь, что мой вариант это всего лишь вариант...
Хотя, а что в этом мире совершенено? Компилятор MS VC 7.1?
... << RSDN@Home 1.1.3 stable >>
Re[6]: Выравнивание! Или как лучше это сделать?!
От: Шахтер Интернет  
Дата: 02.04.04 02:55
Оценка:
Здравствуйте, valytch, Вы писали:

V> Ну и я соглашусь, что мой вариант это всего лишь вариант...

V> Хотя, а что в этом мире совершенено? Компилятор MS VC 7.1?

Не а. Intel 8.0 его хорошо делает.
... << RSDN@Home 1.1.0 stable >>
В XXI век с CCore.
Копай Нео, копай -- летать научишься. © Matrix. Парадоксы
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.