The MASM Forum

General => The Campus => Topic started by: StillLearningMasm on July 16, 2023, 04:50:37 PM

Title: What is the difference between WORD and WORD PTR
Post by: StillLearningMasm on July 16, 2023, 04:50:37 PM
I receintly learned that MASM supports using BYTE, WORD etc without having PTR after it.
What is the difference between WORD and WORD PTR?

I created this code fragment:
mov ax, word [bx]
mov ax, word ptr [bx]

That creates this code:
 00000018  67& 66| 8B 47   mov ax, word [bx] ;same as mov ax,[bx + 2]
      02

 0000001D  67& 66| 8B 07   mov ax, word ptr [bx] ;same as mov ax,[bx]

So what is PTR? I thought it might be the same as offset but it dpesn't seem to be and MASM does a terrible way of explaining it for me.

Thank you,
StillLearningMasm

Title: Re: What is the difference between WORD and WORD PTR
Post by: NoCforMe on July 16, 2023, 06:38:02 PM
Hmm, not sure what assembler you're using, but WORD by itself is meaningless.
WORD PTR means to treat the source operand as a word. It's basically an override of the usual behavior. Commonly used when you're loading a word-size register from something larger, like a doubleword:

    MOV    AX, WORD PTR [DWORD variable]        ;Loads low word of var.
    MOV    AX, WORD PTR [DWORD variable + 2]    ;Loads high word of var.

Didn't the statement with just WORD give you an error?
Title: Re: What is the difference between WORD and WORD PTR
Post by: jj2007 on July 16, 2023, 06:43:25 PM
Quote from: NoCforMe on July 16, 2023, 06:38:02 PMHmm, not sure what assembler you're using, but WORD by itself is meaningless.
...
Didn't the statement with just WORD give you an error?

Indeed. I tested it with a variety of assemblers, and they all give an error.
Title: Re: What is the difference between WORD and WORD PTR
Post by: zedd151 on July 16, 2023, 06:46:31 PM
What version of ml.exe StillLearningMasm? Or is it ml64? Or is it different assembler? Still, there may be a buggy assembler, would be good to know the name and version so others may avoid having the issue you described.
Title: Re: What is the difference between WORD and WORD PTR
Post by: daydreamer on July 16, 2023, 07:25:20 PM
Most usage i done/seen with all kinds of byte ptr,word ptr,dword ptr,qword ptr,real4 ptr,real8 ptr,real10 ptr is using fpu indirect memory adresses
Fld [ebx] real4 ptr
Without "real4 ptr " the Assembler is unable to guess if you want to load a real4,real8,real10,so you get an error
I am not sure if
movz eax,[ebx] byte ptr
Movz eax,[ebx] word ptr
Is needed
Title: Re: What is the difference between WORD and WORD PTR
Post by: NoCforMe on July 16, 2023, 07:37:53 PM
Let's try to keep this simple; the OP is just learning assembler, so no need to further confuse them.

When you transfer data between two things (registers or memory variables) that are the same size, the assembler knows what you're trying to do, so there's no need for any PTR modifiers.

If you're transferring data between two different sized entities, the assembler will throw an error unless you specify that this is what you want to do, by using the PTR modifier:

    MOV    EAX, DWORD_size_variable            ;Same size, no PTR needed
    MOV    AL, BYTE PTR DWORD_size_variable    ;Taking a BYTE out of a DWORD, so need BYTE PTR
    MOV    AX, WORD PTR DWORD_size_variable    ;Having a WORD w/a DWORD, so need WORD PTR

These examples are where the source (the right-hand side) is larger than the destination. You can also do the opposite, loading a larger entity from something defined as a smaller entity:

    MOV    EAX, DWORD PTR BYTE_defined_variable

where a variable defined using DB actually contains a DWORD value (weird, but legal; the variable would have to be at least 4 bytes long for this to work).

Does that make sense now? It's basically another way to get into trouble with the assembler, unless you know what you're doing.
Title: Re: What is the difference between WORD and WORD PTR
Post by: NoCforMe on July 16, 2023, 07:57:17 PM
Here's a real-world example of where you'd need to use PTR. Let's say your program handles the WM_MOUSEMOVE message from Windows, which is sent anytime the mouse moves over one of your windows. The lParam parameter of this message contains the X- and Y-coordinates of the mouse, packed into a DWORD. To get them into two registers you'd use:

    MOV    AX, WORD PTR lParam            ;X-coord. of mouse
    MOV    DX, WORD PTR lParam + 2        ;Y-coord. of mouse

What the first statement does is load a WORD-sized register from a variable that's defined as a DWORD. It loads the low word of the variable--the first 16 bits of the 32-bit variable.

The 2nd statement loads the high word of the variable--the last 16 bits. You need to keep in mind that the X86 processor is "little-endian", which means the low byte/word/doubleword comes before the high byte/word/doubleword, unlike "big-endian" CPUs like the 68000.
Title: Re: What is the difference between WORD and WORD PTR
Post by: NoCforMe on July 16, 2023, 08:03:44 PM
Lastly, hopefully not to confuse you, but here's how you'd really do this in a real-world program (get the mouse coords. into 2 registers). The problem with the previous example is that you have 2 WORD-size registers, which don't really work too well in a 32-bit program. We'd rather have them in EAX and EDX, instead of AX and DX.

No problemo; we'll just use:

    MOVZX    EAX, WORD PTR lParam            ;X-coord. of mouse
    MOVZX    EDX, WORD PTR lParam + 2        ;Y-coord. of mouse

The MOVZX is a really cool instruction that can move a WORD into a DWORD-size register, and fill the other 16 bits with zeroes. (MOVSX does the same thing but copies the sign bit into the upper 16 bits, to preserve the sign of an integer.) WORD PTR is needed here to tell the assembler that we want to take 16 bits from the source.
Title: Re: What is the difference between WORD and WORD PTR
Post by: StillLearningMasm on July 17, 2023, 07:05:49 AM
Here is the code we discussed:

;using MASM version 6 (supports version 5 by using OPTION M510)
option M510

    .386
    .model tiny

    .code

mov al,byte [bx] ;same as mov al,[bx + 1] (no error message)
; (syntax error if no OPTION M510)
mov al,byte ptr [bx] ;same as mov al,[bx]
mov ax, word [bx] ;same as mov ax,[bx + 2] (no error message)
; (syntax error if no OPTION M510)
mov ax, word ptr [bx] ;same as mov ax,[bx]
mov eax, dword [bx] ;same as mov eax,[bx + 4] (no error message)
; (syntax error if no OPTION M510)
mov eax, dword ptr [bx] ;same as mov eax,[bx]

;below are the same examples without size specified for indirect memory
;no errors
mov al,[bx + 1]
mov al,[bx]
mov ax,[bx + 2]
mov ax,[bx]
mov eax,[bx + 4]
mov eax,[bx]

    .data
end
Title: Re: What is the difference between WORD and WORD PTR
Post by: jj2007 on July 17, 2023, 07:15:47 AM
> supports version 5 by using OPTION M510

That could be the problem: Version 5 is 35 years old, and guess what? It wasn't perfect.

Do you have a specific reason to use 16-bit code?
Title: Re: What is the difference between WORD and WORD PTR
Post by: NoCforMe on July 17, 2023, 07:28:50 AM
I guess JJ's question is a valid one. You seem to be mixing 16- and 32-bit code, which doesn't work well.

One statement of yours in particular is kind of Frankenstinian:

mov eax, dword [bx] ;same as mov eax,[bx + 4] (no error message)

The problem is that this is obviously 32-bit code (since you're using EAX), but you're trying to address memory with a 16-bit pointer ([BX]). That probably ain't gonna work.

And I don't see how you can say that mov eax, dword ptr [bx] is the same as mov eax, [bx + 4]. Is that what assembly listing is showing? Seems to me it should be [bx + 0], since you haven't specified a 4-byte offset here. Maybe that's another bug with that old assembler, or a result of a strange instruction construct. In any case, not valid.

Anyhow, looks like you might want to untangle the 32-bit stuff from the 16-bit stuff. (You can still write 16-bit code if you really want to, though it's hard to see a reason why you'd choose that path; that's the bad old world of DOS ...)
Title: Re: What is the difference between WORD and WORD PTR
Post by: _japheth on July 17, 2023, 06:47:54 PM
Quote from: NoCforMe on July 17, 2023, 07:28:50 AMmov eax, dword [bx] ;same as mov eax,[bx + 4] (no error message)

The problem is that this is obviously 32-bit code (since you're using EAX), but you're trying to address memory with a 16-bit pointer ([BX]). That probably ain't gonna work.

Using 32-bit registers is perfectly valid in "16-bit code" and works quite well.

QuoteAnd I don't see how you can say that mov eax, dword ptr [bx] is the same as mov eax, [bx + 4].

If a type like "DWORD" is used without the PTR operator, masm assumes that it's meant to be a short form of "TYPE DWORD", and therefore gives the result 4.

That why masm - even the newer versions - will accept this syntax:

mov eax, [dword] [bx]          ; same as "mov eax,[bx+4]"


Title: Re: What is the difference between WORD and WORD PTR
Post by: NoCforMe on July 17, 2023, 07:02:13 PM
Quote from: _japheth on July 17, 2023, 06:47:54 PMUsing 32-bit registers is perfectly valid in "16-bit code" and works quite well.

Hmm; don't you mean "using 16-bit registers is perfectly valid in 32-bit code"? Which is true; you can access BX as well as BL and EBX. The reason I said it probably wouldn't work is that a 16-bit memory access might well be illegal, at least judging from the addresses I see in OllyDbug with Windows programs. But yes, you can use them (16-bit regs) if you know what you're doing.

Quote
QuoteAnd I don't see how you can say that mov eax, dword ptr [bx] is the same as mov eax, [bx + 4].

If a type like "DWORD" is used without the PTR operator, masm assumes that it's meant to be a short form of "TYPE DWORD", and therefore gives the result 4.

That why masm - even the newer versions - will accept this syntax:

mov eax, [dword] [bx]          ; same as "mov eax,[bx+4]"

Ah, I see. Didn't know that (about TYPE). It's doing what it's supposed to do, but the result is bizarre and not what the OP was looking for.
Title: Re: What is the difference between WORD and WORD PTR
Post by: FORTRANS on July 17, 2023, 11:17:57 PM
Hi,

Quote from: NoCforMe on July 17, 2023, 07:02:13 PM
Quote from: _japheth on July 17, 2023, 06:47:54 PMUsing 32-bit registers is perfectly valid in "16-bit code" and works quite well.

Hmm; don't you mean "using 16-bit registers is perfectly valid in 32-bit code"?

  No, using 32-bit registers works well in 16-bit (MS-DOS) code.  You
do use 16-bit addressing.  Just as you would use 32-bit addressing in
32-bit (Windows) code using 16-bit registers.  Not to mention using 8-bit
registers in either mode.

Cheers,

Steve N.
Title: Re: What is the difference between WORD and WORD PTR
Post by: zedd151 on July 18, 2023, 02:52:34 AM
@FORTRANS:

It is a case of:
Quote from: hutch-- on July 19, 2016, 09:43:29 AM:biggrin:

MASM does not have bugs, it just has features you need to understand.  :P
:biggrin:

Title: Re: What is the difference between WORD and WORD PTR
Post by: NoCforMe on July 18, 2023, 04:29:58 AM
Quote from: FORTRANS on July 17, 2023, 11:17:57 PMHi,

Quote from: NoCforMe on July 17, 2023, 07:02:13 PM
Quote from: _japheth on July 17, 2023, 06:47:54 PMUsing 32-bit registers is perfectly valid in "16-bit code" and works quite well.

Hmm; don't you mean "using 16-bit registers is perfectly valid in 32-bit code"?

  No, using 32-bit registers works well in 16-bit (MS-DOS) code.  You
do use 16-bit addressing.  Just as you would use 32-bit addressing in
32-bit (Windows) code using 16-bit registers.  Not to mention using 8-bit
registers in either mode.

First of all, have we lost the OP here? Hope we haven't scared them off.

Second of all, hmmm, I thought you couldn't use 32-bit anything in 16-bit programming. Isn't that in real mode? Does anyone actually do that, use 32-bit regs in 16-bit mode? Seems a bit ... Frankenstinian to me.
Title: Re: What is the difference between WORD and WORD PTR
Post by: FORTRANS on July 18, 2023, 05:09:17 AM
Quote from: NoCforMe on July 18, 2023, 04:29:58 AMSecond of all, hmmm, I thought you couldn't use 32-bit anything in 16-bit programming.

   I believe you thought wrong in this case.

QuoteIsn't that in real mode?

   Yes, in most cases, DOS is in real mode, or running under some
sort of memory manager that allows real mode programs to run.

QuoteDoes anyone actually do that, use 32-bit regs in 16-bit mode? Seems a bit ... Frankenstinian to me.

   I have done that.  Use 32-bit registers in a DOS program, mainly
to extend loops or counts past 65k iterations.  I would have to check
to make sure of other uses, as it has been a while.

Regards,

Steve N.
Title: Re: What is the difference between WORD and WORD PTR
Post by: NoCforMe on July 18, 2023, 05:49:20 AM
Well. I stand (sit, actually) corrected.

OK, but my other objection (that you really can't use 16-bit registers for memory access in a 32-bit program) is valid. Just loaded up a program in Olly and checked a statement that accesses (the address of) a variable:

MOV EDX,OFFSET EdAsm.0040C94C

You can see that there's no way that value (40C94Ch) will fit into a 16-bit register. So an attempted access with, say, [BX] will fail here.
Title: Re: What is the difference between WORD and WORD PTR
Post by: jj2007 on July 18, 2023, 06:41:48 AM
If you manage to get access to the first 65536 bytes of your address space, mov eax, [bx] will work.
Title: Re: What is the difference between WORD and WORD PTR
Post by: Rockphorr on July 21, 2023, 02:12:46 AM
Quote from: StillLearningMasm on July 16, 2023, 04:50:37 PMI receintly learned that MASM supports using BYTE, WORD etc without having PTR after it.
What is the difference between WORD and WORD PTR?

I created this code fragment:
mov ax, word [bx]
mov ax, word ptr [bx]

That creates this code:
 00000018  67& 66| 8B 47   mov ax, word [bx] ;same as mov ax,[bx + 2]
      02

 0000001D  67& 66| 8B 07   mov ax, word ptr [bx] ;same as mov ax,[bx]

So what is PTR? I thought it might be the same as offset but it dpesn't seem to be and MASM does a terrible way of explaining it for me.

Thank you,
StillLearningMasm



mov ax,[bx]  is equalent  mov ax, word ptr [bx]

when you skip "ptr" it is assembled like mov ax, 2[bx] couse sizeof(word)=2