| UMBC CMSC 211 |
To do this, we must declare them as:
| X | DW | ? | ; an integer variable |
| PX | DD | X | ; a far pointer initialized to ; the address of X |
| PP | DD | ? | ; an uninitialized far pointer |
| LongInt | DD | 123456 | ; a 32-bit integer (long int) |
The null pointer (NULL in C) is supposed to point to nothing and is used to signify a special condition, must be a value that is not allowed to occur, 0:0.
There two special instructions to put a far pointer into a register pair:
| lds | reg, DWordVbl | ; sets ds:reg to the value of DWordVbl |
| les | reg, DWordVbl | ; sets es:reg to the value of DWordVbl |
This assumes that the offset part of the addres comes first in memory, which DD will do for you, and is consistent with the little-endian ordering of bytes. There is no special reverse instruction, to put the register pair into a memory variable. That must be done like this:
| mov | WORD PTR PP, bx | ; set PP to es:bx |
| mov | WORD PTR PP + 2, es | ; |
Suppose that the double word pointer First points to the first element of a linked list. Each node points an element with the name NEXT that points to the next node. We can process the list with the following code:
| les | bx, First | ; es:bx points to ; the first node | |
| ASSSUME | es : NOTHING | ; At assembly time we don't know ; es's segment | |
| ListLoop: | ; | ||
| test | bx, bx | ; Is es:bx null? | |
| jnz | GoOn | ; | |
| mov | ax, es | ; | |
| test | ax, ax | ; can't test a segment register | |
| jz | Done | ; | |
| GoOn: | ; | ||
| ; process node here | ; | ||
| les | bx, es:[ NEXT + bx ] | ; Get the next pointer | |
| Done: | ; |