Title: REGISTERS
1REGISTERS
2REGISTERS
- Here are the 16-bit registers available on all
Intel 8086-compatible microprocessors
16-Bit Pointer Registers
3BP
BP Base Pointer As BX pointers are assumed to be
relative to the DS segment, BP pointers are
relative to the stack segment (SS). You can use a
DS or ES segment override with BP (such as mov
AX, ESBP), but that misses the true power of
BP quickly addressing stack data. Most routines
setup a stack frame to access data passed on the
stack (the BP6 lines we see scattered through
our medium model code). push bp Save
original contents of BP mov bp, sp Set
BP to the stack pointer When Assembly language
routines exit, they restore BP from the stack
pop bp Restore original BP contents
4BP
Arguments passed to your routine on the stack are
addressed as positive offsets from the stack
pointer. Let's look at the relationship between
offsets from BP and data passed to our routines
again. Say your routine requires two integer
arguments the Basic declaration looks something
like this DECLARE SUB Sandwich(Arg1, Arg2)
Following Basic calling conventions, arguments
are pushed on the stack from left to right. The
Basic code to call the routine looks something
like push Arg1 2 bytes on the
stack push Arg2 2 more bytes
call FAR PTR Sandwich 4 additional
bytes for ret
5BP
When the routine gains control, it sets up a
stack frame push bp 2 more bytes mov bp,
sp BP stack pointer Now we have BP pointing
to the value of the stack pointer after we saved
BP. The Stack Frame
6BP
- Don't Assume The Stack Is In DGROUPIn the
medium model, the stack is in DGROUP (usually
abbreviated as SSDS), though you shouldn't make
this assumption for compatibility with future
compilers and operating systems. While BP is
assumed to be SS (Stack Segment) relative, you
can use a segment override to point BP at DGROUP.
7BP
- When you've read everything passed on the stack
and you don't have any local stack variables, you
can use BP as a scratch register. You can also
use BP like BX, to address memory, though
remember that the default segment used with BP is
the stack segment, so you will frequently need to
add a segment override. This example reads a byte
from the extra segment to AL using BP - mov al, BYTE PTR esbp
- Preserve BP If You Change ItBP is reserved by
Microsoft high-level languages. If your procedure
will change the BP register, you must preserve
the register when your routine begins (usually on
the stack), then restore the register when your
routine exits.
8SP
SP - Stack Pointer Everything we do affects the
stack. The stack pointer register keeps track of
data and return addresses, and keeps data from
colliding as we jump between modules. Once the
program's startup code has setup the stack
pointer, the pointer is maintained automatically
as we work. Every time you push or pop a
register, the stack pointer is adjusted for the
data. Whenever you call a routine, the processor
pushes the return address on the stack, then pops
the return address into the instruction pointer
when you exit the routine with a ret instruction.
You cannot directly address memory with the SP
register in real mode. As we've already seen (and
we'll show again), we use the BP register to make
stack addressing easier.
9SP
SP - Stack Pointer The following example places a
near pointer (the address of the next statement)
on the stack with the call instruction. The
second instruction, add SP,2, adjusts the stack
pointer to eliminate the return address. There is
no return address left on the stack, so there's
nowhere to return to. call NEAR PTR _at_F A near
call _at__at_ add sp, 2 Discard the near return
address
10SP
SP - Stack Pointer If you've worked with
non-stack oriented processors and operating
systems (some HP machines, for instance, use a
fixed-size hardware return stack), this
dependence on a user-defined stack sounds at the
very least foolhardy. It works because everyone
follows one simple rule if you change the stack
pointer, put it back when you're through. And to
ensure that worlds don't collide, programs
reserve enough extra space on the stack for any
likely contingency -- then add a bit more just to
be sure. Simple programs allocate about 2K for
the stack large processes add quite a bit extra
for the fudge factor. (Heavy on the fudge,
Microsoft Windows NT 3.x, for instance, uses at
least a 128K stack, and later operating systems
may use a Virtual stack, addressing a megabyte or
more.) Note If you adjust the stack pointer,
you can make room for local data on the stack.
We'll show you how in the "Local Data" section,
in the real book.
11SI
- SI - Source Index
- In addition to use as a general purpose register,
SI is also the source pointer for string and
memory operations. lodsb and lodsw assume that
DSSI point to the source data, while movsb and
movsw assume DSSI point to the source and ESDI
point to the destination. - There are no instructions for accessing just the
high or low byte of SI. - Preserve SIIf your procedure changes the SI
register, you must preserve the register when
your routine begins (usually on the stack), then
restore the register when your routine exits.
12DI
- DI - Destination Index
- Assumed to be ES (Extra Segment) relative. scasb,
stosb and similar instructions take ESDI as the
destination - This example shows the relationship between DSSI
and ESDI. - mov cx, StrLen Number of bytes
- lds si, SourcePtr DSSI Source pointer
- les di, DestPtr ESDI Destination pointer
- rep movsb Copy the string
- Preserve DI If You Change ItIf your procedure
changes the DI register, you must preserve the
register when your routine begins (usually on the
stack), then restore the register when your
routine exits.
13REGISTERS
- Here are the 16-bit registers available on all
Intel 8086-compatible microprocessors
Segment Registers
14CS
CS - Code Segment The CS register always points
to the segment where our code lives -- if program
control passed successfully to our routine, we
can assume the CS register is valid. We never
load CS manually it's loaded automatically by
every far call and every far return instruction.
There is never any reason to pop CS we use push
CS to save the value on the stack, usually to
load the value into another register. This
example loads the ES register with the code
segment push cs Place code segment on the
stack pop es Copy code segment to ES
register While it appears that there is no way
to change the CS register, we do it all the time.
Whenever we do a far call, the current CS value
is saved on the stack, and when the routine ends,
the retf instruction restores the CS register.
15CS
CS - Code Segment In the same way the stack
segment (SS register) is associated with the
stack pointer (SP), the CS register is associated
with the instruction pointer, or IP register. The
instruction pointer is the memory address of the
next instruction the processor will load and
execute. We rarely concern ourselves with the
instruction pointer directly there are few
instructions that work with the instruction
pointer. One way to read the IP register is with
a near call instruction, which places the value
of the instruction pointer on the stack. The
matching near ret instruction pops the value from
the stack into IP. A far call and far ret, push
and pop the CS register and the instruction
pointer.
16DS
DS - Data Segment When the high-level language
passes control to your procedure, DS points to
the default data segment. More accurately, DS
points to DGROUP, which includes all near data
segments. DS is reserved by all high-level
languages, and must be restored when your
procedure exits. We can't load a constant
directly into a segment register. If you need to,
for instance, set the data segment register equal
to the video segment, load the segment to another
register (usually AX), then move the number into
DS.
17ES
- ES - Extra Segment
- This is truly the extra segment register. By
default, it has no value at all, and Microsoft
high-level languages never assume ES is
preserved. Like DS, you can't load the ES
register directly with a constant. - Usually used with DI, though you can tack-on
"ES" as a segment override and use ES with SI,
BX or BP. ES is useful to read a few bytes from
far memory -- such as the ROM BIOS version from
the F000 segment, or the number of lines on the
screen from the 0000 segment. - Don't Use ES as ScratchAvoid using ES as a
scratch register. Even in real mode, where
anything is fair-game, loading segment registers
is slower than general purpose registers. At the
worst, it will make it difficult to update the
code to run in protected mode, where seemingly
innocent looking code crashes the program.
18SS
- SS - Stack Segment
- As the DS register controls the data segment, the
SS register works with the SP register to
maintain the stack segment. - Never change the SS register within a procedure
called from a high-level language unless you have
allocated an internal stack for an exception
handler or other task that requires extra stack
space. Remember to change SS and SP at the same
time, and be sure to disable interrupts when you
do, or any event that uses even a bit of stack
space, such as the clock tick interrupt, will
assume the stack pointer is valid, and can cause
unfortunate things to happen to whoever owns the
memory. - Disable Interrupts When Changing The Stack
SegmentYou must disable interrupts before you
change the stack segment. Since functions called
from high-level languages never alter the stack
segment, we won't discuss the procedure. It is
not necessary to disable interrupts when you
change the stack pointer (SP) to, for instance,
allocate local stack data.
19Intel 32-Bit CPU Registers
General Purpose 32-Bit Registers
20Intel 32-Bit CPU Registers
32-Bit Pointer Registers
21Intel 32-Bit CPU Registers
Segment/Selector Registers