tags:

views:

207

answers:

7

why are the structure declarations in assembly different from those in the win32 api documentation.(i am coming from c++ and trying my hand at assembly language)

for example i got this function prototype from icezelion's tutorials(tutorial3)

WNDCLASSEX STRUCT DWORD
  cbSize            DWORD      ?
  style             DWORD      ?
  lpfnWndProc       DWORD      ?
  cbClsExtra        DWORD      ?
  cbWndExtra        DWORD      ?
  hInstance         DWORD      ?
  hIcon             DWORD      ?
  hCursor           DWORD      ?
  hbrBackground     DWORD      ?
  lpszMenuName      DWORD      ?
  lpszClassName     DWORD      ?
  hIconSm           DWORD      ?
WNDCLASSEX ENDS   

Hey wait...I know that "WNDCLASSEX" structure, in my offline version of the win32 api documentation, its declared as....

typedef struct _WNDCLASSEX {    // wc  
    UINT    cbSize; 
    UINT    style; 
    WNDPROC lpfnWndProc; 
    int     cbClsExtra; 
    int     cbWndExtra; 
    HANDLE  hInstance; 
    HICON   hIcon; 
    HCURSOR hCursor; 
    HBRUSH  hbrBackground; 
    LPCTSTR lpszMenuName; 
    LPCTSTR lpszClassName; 
    HICON   hIconSm; 
} WNDCLASSEX; 

Why is it that the asm version uses DWORD's only contrary to what is in the win32 api documentation?
Am i using the wrong docs or what? and if i am can someone post me a download link for WIN32 api documentation meant for asm programmers?
Help, am confused.

Edited: Here is the link to the tutorial i was refering to:

iczelion's win32 asm tutorial 3

+1  A: 

WNDPROC, UINT, etc., are defined in the C headers, so there is no direct ASM equivilent. They are all DWORD sized quantities on 32-bit systems, which is why that tutorial produces working code.

Michael
+4  A: 

The size of all those different C types is DWORD. Assembly is NOT strongly typed - all it knows about each variable is the number of bytes.

AShelly
+7  A: 

DWORDS are a 32-bit type on 32-bit windows, as are all the types in the C version of the structure. The two are therefore compatible.

anon
Note: type sizes (if you're using 16-, 32- or 64-bit ints, among other things) are defined in limits.h. This size varies between platforms and operating systems (where they exist), but is typically defined to be the same as the register width of the system.
David Lively
Actually a 32bit type on _all_ versions of Windows, 16 bit, 32 bit and 64 bit flavors of Windows all treat DWORD as a 32 bit unsigned int.
John Knoeller
WORD is typically defined as 16 bits, which lakes a double word (DWORD) 32. However, this isn't guaranteed on all platforms (Linux, *ix, embedded systems, etc).
David Lively
+5  A: 

Assembly language is typeless - DWORD and other keywords merely indicate the number of bytes that should be reserved for a specific entity. In fact, since DWORD and its cousins do not represent opcodes/mnemonics, they are really features of the macro preprocessor.

C/C++ types, like those of other languages, are constrained by rules such as endian-ness, where the sign bit goes, what casts, converts and assignments are possible, etc. The C version of the structure you provided is more specific than the assembly language version, but is compatible.

David Lively
what do you mean that it is not compatible? it seems to be working
Dr Deo
I said "not incompatible." Pardon my double-negative, but that means that it *is* compatible. Corrected in text.
David Lively
+2  A: 

At one time (16-bit Windows) these types had different sizes. During the migration to Win32, they all ended up as 32-bit data types. As such, a DWORD is compatible with all of them, to at least some degree.

Contrary to popular belief, however, assembly language does (or at least can) have types and even pretty fair type safety. Just for example, consider what happens when you do something like:

mov lpszMenuName[ecx], 0

With lpszMenuName defined as a DWORD, the assembler won't accept this, because the '0' could be a byte, a word, a dword or (in a 64-bit world) a qword. To make it work, you have to add (essentially) a type cast:

mov byte ptr lpszMenuName[ecx], 0

So the assembler knows you want to write a single byte. Alternatively, you can define lpszMenuName as:

lpszMenuName ptr byte

In which case, the assembler will know it should treat it as pointing at a byte without explicitly stating that each time.

Jerry Coffin
"During the migration to Win32, they all ended up as 32-bit data types" Do you have any links/citations
Dr Deo
@Dr. Deo:Are you asking for a reference showing that they're now all 32-bit types, or that some of them used to be 16-bit types?
Jerry Coffin
+1  A: 
tommieb75
+1  A: 

In fact, MASM 6+ supports a form of typing, so you could have your structure in MASM similar to the one you have in C. But you would have to recreate the type hierarchy first, and you'd soon notice that the benefits of typing with MASM are somehow limited (been there, done that). I suggest you Google the MASM 6 Programmer's Reference PDF file: It rather clearly explains of the "HLL" goodies in MASM, including typing, and includes a number of examples. One copy seems to be available at the link below, but there are others floating around.

http://www.microlab.teipat.gr/upload/arxeshy/Microsoft_MASM_Programmers_Guide_v6.zip

filofel