warray | WORD | 1, 2, 3, 4 | ; declares a four-element array of 16-bit values |
dwarray | DWORD | 0FFFFFFFFh, 789ABCDEh | ; declares a two-element array of 32-bit values |
myString | db | "Hello, World!",0 | ; declares a null-terminated string |
Since these are sequential declarations, they would appear in memory as collection of bytes arranged in the following order (assuming the data is stored starting at address 0000H):
Value At Each Byte | 01 | 00 | 02 | 00 | 03 | 00 | 04 | 00 | FF | FF | FF | FF | DE | BC | 9A | 78 | 'H' | 'e' | 'l' | 'l' | 'o' | ',' | ' ' | 'W' | 'o' | 'r' | 'l' | 'd' | '!' | 00 |
Address Of Each Byte | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | A | B | C | D | E | F | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 1A | 1B | 1C | 1D |
Variable | Address | C Notation | Assembly Notation |
---|---|---|---|
warray | 00 | warray[ 0 ] | warray |
02 | warray[ 1 ] | warray + 2 | |
04 | warray[ 2 ] | warray + 4 | |
06 | warray[ 3 ] | warray + 6 | |
dwarray | 08 | dwarray[ 0 ] | dwarray |
0C | dwarray[ 1 ] | dwarray + 4 | |
myString | 10 | myString[ 0 ] | myString |
12 | myString[ 1 ] | myString + 1 | |
13 | myString[ 2 ] | myString + 2 | |
14 | myString[ 3 ] | myString + 3 | |
15 | myString[ 4 ] | myString + 4 | |
16 | myString[ 5 ] | myString + 5 | |
17 | myString[ 6 ] | myString + 6 | |
18 | myString[ 7 ] | myString + 7 | |
19 | myString[ 8 ] | myString + 8 | |
1A | myString[ 9 ] | myString + 9 | |
1B | myString[ 10 ] | myString + 0AH | |
1C | myString[ 11 ] | myString + 0BH | |
1D | myString[ 12 ] | myString + 0CH |
NOTE: Notice that the word and double word values are stored in little-endian order. The characters are one-byte units and stored as given.
array1 dd 1, 2, 3, 4, 5 ; This declares and initializes a 5-element array with the ; values 1, 2, 3, 4 and 5 array2 dd 5 dup ( 0 ) ; This declares and initializes a 5-element array with zeroes. array3 dd 5 dup( ? ) ; This declares a 5-element array but does not initialize it.
Follow these steps when using structures:
The fields are declared and initialized in exactly the same manner as simple variables are. Structures can be nested inside other structures.
WNDCLASSEX STRUCT 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
WinMain proc hInst :DWORD, hPrevInst :DWORD, CmdLine :DWORD, CmdShow :DWORD ;==================== ; Put LOCALs on stack ;==================== LOCAL wc :WNDCLASSEX LOCAL msg :MSG LOCAL Wwd :DWORD LOCAL Wht :DWORD LOCAL Wtx :DWORD LOCAL Wty :DWORD szText szClassName,"Generic_Class" ;================================================== ; Fill WNDCLASSEX structure with required variables ;================================================== mov wc.cbSize, sizeof WNDCLASSEX mov wc.style, CS_HREDRAW or CS_VREDRAW \ or CS_BYTEALIGNWINDOW mov wc.lpfnWndProc, offset WndProc ; address of WndProc mov wc.cbClsExtra, NULL mov wc.cbWndExtra, NULL m2m wc.hInstance, hInst ; instance handle mov wc.hbrBackground, COLOR_BTNFACE+1 ; system color mov wc.lpszMenuName, NULL mov wc.lpszClassName, offset szClassName ; window class name invoke LoadIcon,hInst,500 ; icon ID ; resource icon mov wc.hIcon, eax invoke LoadCursor,NULL,IDC_ARROW ; system cursor mov wc.hCursor, eax mov wc.hIconSm, 0 invoke RegisterClassEx, ADDR wc ; register the window class
Records are bytes, words, or doublewords in which the individual bits or groups of bits are considered fields. In general, the three steps for using record variables are the same as those for using other complex data types:
The fields are given a size in number of bits. Once it is defined, you can use the record variable as an operand in assembler statements. The WIDTH operator (used only with records) returns the width in bits of a record or record field. The MASK operator reutrns a bit mask for the bit positions occupied by the given record field. A bit in the mask contains a 1 if that bit corresponds to a bit field. Bits are initialized by putting the values for each field inside the < and > symbols.
.DATA | |||
COLOR | RECORD | blink:1, back:3, intense:1, fore:3 | |
message | COLOR | <1, 5, 1, 1> | |
wblink | EQU | WIDTH blink | ;"wblink" = 1 |
wback | EQU | WIDTH back | ;"wback" = 3 |
wintens | EQU | WIDTH intense | ;"wintens" = 1 |
wfore | EQU | WIDTH fore | ;"wfore" ; = 3 |
wcolor | EQU | WIDTH COLOR | ;"wcolor" = 8 |
.CODE | |||
mov | ah, message | ;load initial 1101 1001 | |
and | ah, NOT MASK back | ;Turn off AND 1000 1111 | |
;"back" -------------- | |||
; 1000 1001 | |||
or | ah, MASK blink | ;Turn on OR 1000 0000 | |
;"blink" -------------- | |||
; 1000 1001 | |||
xor | ah, MASK intense | ;Turn off XOR 0000 1000 | |
;"intense" -------------- | |||
; 1000 0001 |