The ASSUME Statement
One reason for the use of SEGMENT directives is to allow the
assembler to do most of the work in deciding whether to use the
default segment register, or provide a segment override. First the
programming must define the contents of the segment registers in the form
of:
ASSUME SegReg : SegName
The segment name can also be the keyword NOTHING which means that
it is unknown what is in the specificed register. The default is
what we have used so far:
ASSUME cs : @code, ds : @data, es : NOTHING
An ASSUME for a particular register applies to all a particular register applies to all the program text
which follows it in line-by-line order, not execution order, up
to the next ASSUME statement for that specific register.
Loading segment registers and ASSUMEing their contents are two
entirely independent operations, and both are required when
a segment register changes. (It might help to remember that the mov
instruction is done at run-time, and the ASSUME is done at assembly time.)
Since the default ASSUME statement is in effect we do not have
to do it when we load the ds register at the very beginning of a program.
- ASSUME never changes any segment register.
- Changing segment registers never changes ASSUMEs.
Not getting this correct can have you pointed to the wrong part
of memory, which is called a splatter bug. This is
difficult to find and fix, because sometimes it will execute
correctly and other times it will not.
Moving data
Suppose that ds:si and es:di are the starting address to two word
arrays (that do not overlap) and that they contain cx words:
| CopyLoop: | | | |
| | mov | ax, [si] | ; default ds used for source |
| | mov | es :[di], ax | ; explicit overrride required |
| | add | si, 2 | |
| | add | di, 2 | |
| | loop | CopyLoop | |
Alternatively, we can use pointers:
| | mov | bx, 0 | |
| CopyLoop: | | | |
| | mov | ax, [bx + si] | |
| | mov | es :[bx + di], ax | |
| | add | bx, 2 | |
| | loop | CopyLoop | |
UMBC |
CSEE