I was reading Ernie's wesite which reccommended that a structure be created to access the high and low words of a dword.

While this is not a bad idea, it forces someone to use a structure name (can't use DWORD) and on existing code the code must be changed

I think that the best solution is with macros.



WORD0 MACRO pointer
EXITM <WORD PTR &pointer>
ENDM

WORD1 MACRO pointer
EXITM <WORD PTR (&pointer + sizeof WORD)>
ENDM


example code:



.data
var1 DWORD 0

.code
mov ax, WORD0(var1) ; ax = lowword(var1)
mov bx, WORD1(var1) ; bx = hiword(var1)


Notes:

These macros simply override the type that the lable
var1 points to. (The second one adds 2 to this pointer to get
the hiword.)

This method can be reused to get BYTE0, BYTE1, BYTE2, and BYTE3 of a DWORD.

Also, these macros can get the first two words of a QWORD and more macros can be written to get the other two words.
WORD2 would have "(sizeof WORD) * 2" instead of "sizeof WORD"
etc.

I hope this helps people because it means that they won't have to use a stucture and won't have to rewite all code for DWORDs.

I sure this topic shouldn't be dwelled on too much. Ernie agrees.


Ernie: And I am done too. I've spent way too much time on this one little topic.
Posted on 2002-01-09 13:16:27 by BigBadBob
WORD0 EQU <WORD PTR>

WORD1 EQU <WORD PTR [2]>

mov ax, WORD0 [edx]
mov ax, WORD1 [edx]
I'm sure there are several ways to tackle this one.
mov ax, [edx]

mov ax, [edx+2]
Posted on 2002-01-09 13:26:25 by bitRAKE
Thats a cool trick BitRake...

The word pointer [2], is adding 2 bytes after the base Address pointed to right?

NaN
Posted on 2002-01-09 15:36:59 by NaN
Yeap (2+ would work too), I'd like it to be something like:
mov ax, WORD0 PTR [edx]

mov ax, WORD1 PTR [edx]
...to be consistent with current notation. So this might work better:
WORD0 EQU <WORD>

WORD1 EQU <2 + WORD>
Posted on 2002-01-09 16:06:07 by bitRAKE
Can't....fight...trying....not...to..return...to this...subject...


AGGGHHHHH!

OK, so you don't want to redefine wParam or lParam as a PackedDW, no problem.

CAST them that way.



packedDW UNION
value DWORD ?
STRUCT
loword WORD ?
hiword WORD ?
ENDS
packedDW ENDS


movsx eax, lParam.packedDW.loword

movsx eax, lParam.packedDW.hiword

mov eax, lParam


MASM will get your point. And notice I didn't need a pointer to lParam in edx, I can get what I want without that.

MY whole point was you need not go shifting or ANDing to block out a portion of a dword to just get a word out of it.


Hey, it's your cat. Skin it any way you like.
Posted on 2002-01-09 19:20:03 by Ernie
There are many ways to skin a cat, if the WORD value is in a 32 bit register, if its the Low WORD, its already in AX, if its in the HIGH WORD of the register, ROL or ROR the register by 16 and the WORD is now in AX.

If its a memory operand, just increment the index by 2 to get the high WORD.

Regards,

hutch@movsd.com
Posted on 2002-01-09 23:18:52 by hutch--
I was going to respond to bitrake's first reply but hesitated.

I didn't want to say that your notation was a little confusing, and look, you corrected yourself. You're kind of like me, I would want the best notation to be used.

One thing though. Using WORD1 PTR to "cast" a variable to it's second word? If you think about it you shouldn't be able to "cast" to a "second piece" of a variable. Casting was meant to transform a variable into another type. In such a case, I believe, the original notation should be used.
WORD PTR var + 2.


The reason that I prefer my method is that it makes more sense to me. I have a function (macro) that returns the piece of the variable that I want.

This is my own opinion and nobody's way is incorrect.:grin:

Ernie you counldn't help yourself, could you? (I had a feeling you'd respond);)
Posted on 2002-01-10 00:17:56 by BigBadBob