Как в C мы можем читать и создавать DWORD
переменные с младшим и старшим словом, а также младшим и старшим байтами?
Переменная DWORD с младшим / старшим словом и младшим / старшим байтом
Ответы (3)
В Win32 DWORD является 32-битным беззнаковым целое число. В другом контексте это могло означать что-то еще.
Приняв определение Win32 (и другие определения типов Win32):
BYTE lsb = 0x11 :
BYTE next_lsb = 0x22 :
BYTE next_msb = 0x33 :
BYTE msb = 0x44 :
DWORD dword_from_bytes = (msb << 24) | (next_msb << 16) | (next_lsb << 8) | lsb ;
dword_from_bytes
будет иметь значение 0x44332211
.
Так же:
WORD lsw = 0x1111 :
WORD msw = 0x2222 :
DWORD dword_from_words = (msw << 16) | lsw ;
dword_from_words
будет иметь значение 0x22221111
.
Чтобы извлечь, скажем, третий байт из dword_from_bytes
, например:
next_msb = (dword_from_bytes >> 16) & 0xff ;
хотя & 0xff
не является строго необходимым в этом случае, учитывая тип next_msb
, но если тип приемника был больше 8 бит, он замаскирует биты MSB.
person
Clifford
schedule
21.11.2010
Теперь это обретает смысл. Но что на самом деле означают
<<
, >>
и |
? Спасибо!
- person Midas; 21.11.2010
Лучше использовать специальные макросы, такие как
HIWORD
, LOWORD
, MAKELONG
и т. Д. Поскольку разные процессоры используют разный порядок байтов (прямой / большой порядок байтов и т. Д.)
- person valdo; 21.11.2010
Ладно, не суть. Я прочитал документацию о побитовых операторах и теперь понимаю, как это работает!
- person Midas; 21.11.2010
@valdo: Хотя я согласен с тем, что следует использовать макросы, определенные API, порядок байтов не является проблемой;
(msw << 16)
, например, всегда будет помещать значение в старшее слово независимо от порядка байтов. Есть и другие макросы для обмена данными между машинами с разным порядком байтов. Что они делают, так это инкапсулируют знания о размерах слов, определенных API, чтобы обеспечить согласованность и избежать ошибок.
- person Clifford; 22.11.2010
WinAPI предоставляет макросы для манипуляций с этими типами, например:
person
Puppy
schedule
21.11.2010
кроме того, у вас есть
HIBYTE
и LOBYTE
соответственно
- person Hanan N.; 01.10.2013
#include <stdint.h>
#include <stdio.h>
typedef union _little_endian{
struct _word{
union _msw{
struct _msw_byte{
uint8_t MSB;
uint8_t LSB;
} __attribute__((__packed__)) MSW_BYTE;
uint16_t WORD;
} MSW;
union _lsw{
struct _lsw_byte{
uint8_t MSB;
uint8_t LSB;
} __attribute__((__packed__)) LSW_BYTE;
uint16_t WORD;
} LSW;
} __attribute__((__packed__)) WORD;
uint32_t DWORD;
} DWORD;
int main(int argc, char *argv[]){
DWORD test1;
test1.WORD.MSW.MSW_BYTE.MSB = 1;
test1.WORD.MSW.MSW_BYTE.LSB = 2;
test1.WORD.LSW.LSW_BYTE.MSB = 3;
test1.WORD.LSW.LSW_BYTE.LSB = 4;
printf("test1: hex=%x uint=%u\n", test1.DWORD, test1.DWORD);
DWORD test2;
test2.DWORD = 0x08080404;
printf("test2: hex=%x uint=%u\n", test2.DWORD, test2.DWORD);
printf("test2.WORD.MSW.MSW_BYTE.MSB: uint=%u\n", test2.WORD.MSW.MSW_BYTE.MSB);
printf("test2.WORD.MSW.MSW_BYTE.LSB: uint=%u\n", test2.WORD.MSW.MSW_BYTE.LSB);
printf("test2.WORD.LSW.LSW_BYTE.MSB: uint=%u\n", test2.WORD.LSW.LSW_BYTE.MSB);
printf("test2.WORD.LSW.LSW_BYTE.LSB: uint=%u\n", test2.WORD.LSW.LSW_BYTE.LSB);
return 0;
}
Я предпочитаю использовать комбинацию структур и объединений.
Вывод:
test1: hex=4030201 uint=67305985
test2: hex=8080404 uint=134743044
test2.WORD.MSW.MSW_BYTE.MSB: uint=4
test2.WORD.MSW.MSW_BYTE.LSB: uint=4
test2.WORD.LSW.LSW_BYTE.MSB: uint=8
test2.WORD.LSW.LSW_BYTE.LSB: uint=8
person
paladin
schedule
12.10.2020