(Update: Michael Petch says some MASM or MASM compatible assemblers allow size and segment overrides inside the brackets. But update2: not all, so this may actually have been the problem. It's at least more standard style so I'd recommend always doing that.)
In normal MASM syntax you want MOV [CARLOC], DX
. Depending how you declared carloc
, you may still need mov word ptr [CARLOC], dx
, but DS:
is already the default segment.
If you wanted to be explicit about it, MOV word ptr ds:[CARLOC], dx
but I recommend leaving out redundant DS prefixes in the asm source because some assemblers include a redundant DS prefix in the machine code! The only time DS: isn't redundant is when used with ds:[bp]
or ebp, or ds:[esp]
, which imply SS as the default segment.
With MASM, ds:
prefixes are also requires with numeric absolute addresses. Otherwise that's treated as an immediate (regardless of brackets) which of course can't be a destination. With a definition like CARLOC equ $-2
, you will need ds:[CARLOC]
. Apparently MASM does not put useless ds
prefixes in the machine code so you don't have to worry with that assembler.
If you need a CS/DS/ES/FS/GS/SS prefix, the standard syntax is to put it outside the brackets:
MOV AL, ES:[0017H]
The AL destination implies byte ptr
operand-size, which also goes outside the brackets. Look at disassembler output for example.
And into BYTE PTR ES:0017H
which compiled the code successfully,
Yes, that is valid syntax: the brackets are optional in some cases (including with absolute addresses or symbols). Many people recommend always using brackets around memory operands (as opposed to OFFSET symbol
immediates) to make it clearer for human readers.
If you are going to use brackets, they go after the size ptr
and seg:
overrides.
the program ran but did not work correctly
Then either your code has other bugs beyond the syntax errors.
Or if you're trying to build this into a Windows executable: Of course it doesn't work to take code written for DOS (real mode, in control of the whole machine) and build it as a 32-bit or 64-bit Windows executable (protected mode or 64-bit mode, ring 3 under an OS). The system-call ABI and even API are totally different, too: those are different OSes and the DOS API isn't available to Windows executables.
Michael also suggested that a USE32 or other directive might make MASM try to save you from yourself and reject use of segmentation in code that's supposed to run with a flat memory model. But if es:[17H]
works then that's probably not it.