VC 2008 Bit Fields


Author: Dave
Date: 12.12.12 - 7:50pm



This sent me for a loop. When porting some gcc code over to compile under Visual Studio 2008 the following bit field error cropped up...
#pragma pack(push, 1)
//sizeof(mtx_header_t) = c = 12 bytes or 96 bits should only be 80 bits... 
typedef struct {  //00 11 11 11 22 22 22 33 33 33 99 (10 bytes)
    unsigned version   :  8;  //00               1 byte
    unsigned distance  : 24;  //   11 11 11           3 bytes
    unsigned dataoffset : 24; //            22 22 22     3 bytes
    unsigned codeoffset : 24; //                     33 33 33   3 bytes
} mtx_header_t;                 

#pragma pack(pop)

mtx_header_t h;

void main(void){
	
	unsigned char tmp[11] = { 0, 0x11,0x11,0x11, 0x22,0x22,0x22 ,0x33,0x33,0x33, 0x99};
	
	memset(&h, 0, sizeof(h) );
	memcpy(&h, (void*)tmp, 11);

	printf("sizeof(mtx_header_t) = %d\n", sizeof(h) );

	printf("address of h: %x\n", &h);
	printf("version: %x\n", h.version );
	printf("distance: %x\n", h.distance );
	printf("dataoffset: %x\n", h.dataoffset );
	printf("codeoffset: %x\n", h.codeoffset );

	getch();
}
Output is:
sizeof(mtx_header_t) = 12
address of h: 495650
version: 0
distance: 111111
dataoffset: 222222
codeoffset: 993333
and relevant disassembly:
	printf("version: %x\n", h.version );
0042F8B9  mov         eax,dword ptr [_h (495650h)] 
0042F8BE  and         eax,0FFh 
0042F8C3  push        eax  
0042F8C4  push        offset string "version: %x\n" (482E14h) 
0042F8C9  call        @ILT+4440(_printf) (42C15Dh) 
0042F8CE  add         esp,8 
	printf("distance: %x\n", h.distance );
0042F8D1  mov         eax,dword ptr [_h (495650h)] 
0042F8D6  shr         eax,8 
0042F8D9  and         eax,0FFFFFFh 
0042F8DE  push        eax  
0042F8DF  push        offset string "distance: %x\n" (482D00h) 
0042F8E4  call        @ILT+4440(_printf) (42C15Dh) 
0042F8E9  add         esp,8 
	printf("dataoffset: %x\n", h.dataoffset );
0042F8EC  mov         eax,dword ptr [_h+4 (495654h)] 
0042F8F1  and         eax,0FFFFFFh 
0042F8F6  push        eax  
0042F8F7  push        offset string "dataoffset: %x\n" (482C7Ch) 
0042F8FC  call        @ILT+4440(_printf) (42C15Dh) 
0042F901  add         esp,8 
	printf("codeoffset: %x\n", h.codeoffset );
0042F904  mov         eax,dword ptr [_h+8 (495658h)] ;  I expected this to be _h+7 ! 
0042F909  and         eax,0FFFFFFh 
0042F90E  push        eax  
0042F90F  push        offset string "codeoffset: %x\n" (482C6Ch) 
0042F914  call        @ILT+4440(_printf) (42C15Dh) 
I havent found a way to fix this, other than to define my own header structure using integral types and load it manually...
typedef struct {                
    unsigned char version;      
    unsigned int distance;     
    unsigned int dataoffset;   
    unsigned int codeoffset;  
} myHead;
 
myHead head;
memset(&head, 0, sizeof(myHead));
memcpy(&head.version , data, 1);
memcpy(&head.distance , data+1, 3);
memcpy(&head.dataoffset, data+4, 3);
memcpy(&head.codeoffset, data+7, 3);
pooooooop. That cost me some hairy debugging...




Comments: (0)

 
Leave Comment:
Name:
Email: (not shown)
Message: (Required)
Math Question: 99 + 42 = ? followed by the letter: P 



About Me
More Blogs
Main Site
Posts: (All)
2020 ( 3 )
2019 ( 5 )
2018 ( 6 )
2017 ( 6 )
2016 ( 22 )
2015 ( 16 )
2014 ( 25 )
2013 ( 4 )
2012 (10)
     VC 2008 Bit Fields
     Speed trap
     C# Db Class Generator
     VB6 vrs .NET (again)
     FireFox Whois Extension
     git and vb6
     Code Additions
     Compiled date to string
     C# ListView Sorter
     VB6 Wish List
2011 (7)
     C# Process Injection
     CAPTCHA Bots
     C# PE Offset Calculator
     VB6 Async Download
     Show Desktop
     coding philosophy
     Code release
2010 ( 11 )
2009 ( 3 )