Question

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

Was it helpful?

Solution

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.

OTHER TIPS

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.

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.

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.

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.

In assembly, regardless of whether a high level structure has pointers or ints, the reality is that their associated high-level datatypes are of BYTE, WORD and DWORD, in your case, the structure are all 32 bit hence DWORD (a WORD is 16bit, DWORD is 32bits). Do not be mislead into thinking the structure in assembly is different to the structure in C, it is very much the same. Assembler has primitive data types, regardless of pointers, structures etc, what sets them apart is how it is loaded into a register (depending on the syntax):

mov eax, dword ptr [bx]

This assembler sample is a demonstration of loading the eax register with the value pointed to by the bx register, effectively same thing as

int bx = 5;
int *eax;
ptr = &bx;

Hope this helps, Best regards, Tom.

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

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top