Category : Assembly Language Source Code
Archive   : ASMTUT2.ZIP
Filename : CHAP3.DOC

Output of file : CHAP3.DOC contained in archive : ASMTUT2.ZIP



We are now going to introduce both the 8086 registers and a
program for looking at them. You are going to get information
flying at you at a rapid pace, so read both this and the next
chapter carefully and slowly.


The 8086 has a number of registers. Remember, registers are
places for storing data that are internal to the 8086 chip. They
are much faster, but there are very few of them.

There are 6 registers that you can use for addition and subtrac-
tion of word (2 byte) sized numbers, as well as logical opera-
tions on word (2 byte) numbers or data. These registers are AX,
BX, CX, DX, SI, DI. In addition, there is a register which works
the same way, but has a special function in all high-level
languages (Basic, Pascal, C, etc.). This is BP, the base pointer.

There is one more register that performs the same operations as
the above seven, but it is RESERVED for special use and should
never be used for anything. It is called SP (the stack pointer).

There are 4 registers that tell the 8086 which memory segments
you are in. They just sit there and help the 8086 find things in
memory. You will learn how they work later. They are CS, DS, SS,
ES. (That is Code Segment, Data Segment, Stack Segment and Extra
Segment respectively).

There is the flags register which contains all the information
the 8086 needs to evaluate its state. We will learn about this
later. The flags register has no name, and there are machine
instructions for manipulating individual flags in the register.

Finally, there is IP, the instruction pointer, which points to
the machine instructions. You have no direct access to this,
which is good because you would screw it up for certain. The 8086
handles the IP automatically and correctly.

One word (two bytes or 16 bits) is the largest piece of data that
the 8086 can handle naturally. It is possible to handle larger
things, but we do it through software (which is slower), not
hardware (which is faster). Sometimes we want to handle things
one byte at a time as when we work with characters. The 8086
gives us this possibility by letting us divide the AX, BX, CX,
and DX registers into an upper half and a lower half. For any or
all of these registers, we can replace one 2 byte register by two
1 byte registers. The data in the full register stays the same,
but we can look at each half. The two parts of AX are called AH
(for A high) and AL (for A low).


Chapter 3 - ASMHELP.OBJ 17

This is the 16 bit binary number 0 in the AX register. Using AX
allows us to manipulate all 16 bits. Using AH allows us to
manipulate the upper 8 bits (without affecting the lower 8 bits),
and using AL allows us to manipulate the lower 8 bits without
affecting the upper 8 bits. Similarly, for BX we have BH, BL, for
CX we have CH, CL, and for DX we have DH, DL.


We have named all the registers, now let's take a look at them.
Included in the module asmhelp.obj is a program called show_regs.
It shows all the above registers on the top 10 lines of your
screen and allows you to enter data normally underneath.

When you call show_regs, it puts the current value of all the
registers on the screen. Those values stay on the screen until
the next call - i.e. the program does not change what is on the
screen even though the registers may be changing value. You need
to call show_regs every time that you want to see the current
values of the registers.

The first time you call show_regs, it clears the screen so you
should call it right at the beginning of the program in order to
initialize the screen.

This time we want temp2.asm for a template; we will call this
program prog3.asm, so make a copy of temp2.asm and give it the
new name. Let's take a look at it. The only differences are (1)
there are a lot more programs in the EXTRN statements and (2) in
the data segment DATASTUFF there are these definitons:

ax_byte db 2
bx_byte db 2
cx_byte db 2

These will be used for show_regs later, but you need to learn a
few assembler instructions first.

Here's our next program:

call show_regs

call get_hex
call show_regs

call get_num
call show_regs

jmp label_one

+ + + + + + + + END CODE ABOVE THIS LINE

The PC Assembler Tutor 18

That's all the program does. It asks for a number, then calls
show_regs to show us what is in the registers. Note that one of
the numbers is hex while the other number is decimal.

Compile this, and link it with

>link prog3+\asmhelp ;

and we're ready to go.

The program reads information in the computer to find out what
kind of monitor you have and where the screen output goes. It
then puts the register information on the top lines. If it
doesn't appear there, we have a screwup somewhere. The text
should appear in black and white, but if you have a color monitor
you can make it a blue background with white letters.{1}

*********************** SCREEN SHOT ***************************

AX 19825 SI 00000
BX 00000 DI 00256
CX 00255 BP 17113
DX 02596 SP 00508

CS 0AA4H DS 0A54H ES 0A24H SS 0A34H IP 0018H

+ x + x E COUNT 00003


The PC Assembler Helper Version 1.0
Copyright (C) 1989 Chuck Nelson All rights reserved.
Enter a two byte hex number 4df9
Enter any decimal number +19825
Enter a two byte hex number


This is how the screen looks after entering first a hex number,
then a decimal number. The numbers in the registers will probably
be different for you. Note that AX contains the last number that
was entered. On the left side you will see the AX, BX, CX and DX

1 To make a blue background and white letters, insert the code
"call set_blue" before the FIRST "call show_regs". i.e.:

call set_blue
call show_regs


This only works if it is allowed by the video board.

Chapter 3 - ASMHELP.OBJ 19

registers. For the time being, these registers will display
unsigned numbers. On the right are the SI, DI, BP and SP
registers. They are also unsigned numbers for the moment. Below
that are the segment registers CS, DS, ES, and SS and the
instruction pointer (IP). These are hex numbers and will always
be hex numbers. The bottom line has OF, DF, IEF, etc. These are
the flags, and the marking underneath them (either a blank or
some character) tells how they are set. Finally we have COUNT.
This has nothing to do with the 8086. It is a counter that is
incremented each time you call show_regs.

Keep entering numbers and watch the registers. You will notice
that three things are changing - AX, IP and COUNT. AX has the
last number you entered and IP keeps changing. Write down the
value of IP each time it changes. It goes back and forth between
two numbers. That is because you call show_regs in two different
places in the loop, {2} and those are two different places in
memory where the 8086 is reading the machine code.

Why is AX changing? You may have wondered in prog1.asm and
prog2.asm how that information was going back and forth between
your program and asmhelp.obj. The answer is that in all the
programs in asmhelp.obj, if you need to pass information, it is
passed via register AX. This is not the normal way to pass
information. The normal way is more elegant but more complicated.
We will cover that much later. The counter, of course, increases
by 1 each time you call show_regs.

Try entering a few more numbers and then it's time to go on to
the next program.


Obviously, we want to move data from memory to the 8086, from the
8086 to memory, and between registers. We have the following

(1) move from a register to memory
(2) move from memory to a register
(3) move a constant to memory
(4) move a constant to a register
(5) move from one register to another register

That's it. There is no 8086 instruction that moves a single word
or a byte from one place in memory to another.

The move mnemonic for the 8086 is "mov".{3} We need some sample

2 IP actually has three different values, since you call
show_regs once before you enter the loop.

3 A mnemonic is a name for a machine instruction, which sounds
like what the instruction is supposed to do - MOV for move, SUB
for subtract, IMUL for integer multiplication, etc.

The PC Assembler Tutor 20


this_year dw 1989
total dw ?
average dw ?
time dw 7

age db ? ; I hope you aren't older than 255
poem db "In 1492 Columbus played a mean kazoo."
secret_code db 3Bh
character db ?

Here is some sample code. To move from register to memory, we

mov total, ax
mov time, si
mov age, cl
mov character, bh

The first thing that strikes the eye is that the destination is
on the left and the source is on the right.{4} This is standard
for the 8086 instruction set, and it's going to take some getting
used to. DESTINATION ON LEFT, SOURCE ON RIGHT. You are going to
blow this one from time to time, so always double check to make
sure that they are in the right order.

Also note that the 1 byte registers are matched up with 1 byte
variables, and 2 byte registers are matched up with 2 byte data.
If the sizes don't match, the assembler will complain.{5} Thus:

mov age, ax

is an illegal instruction.

For examples of memory to register moves, we have:

mov ch, secret_code
mov di, this_year
mov dl, poem ; moves 'I' to dl
mov bx, time

4 The computer community likes the words "destination" and
"source". "Source" means FROM, and "destination" means TO. The
8086 instruction set is designed:


which is exactly opposite to the way you would say it in an
English sentence. For the 8086, it is always destination on the
left, source on the right.

5 Half register and full register operations have different
machine codes, and the assembler needs to know which code to use,
so the two things must be the same number of bytes.

Chapter 3 - ASMHELP.OBJ 21

Once again: (1) DESTINATION ON LEFT, SOURCE ON RIGHT, and (2) the
sizes of the two objects must match.

For constant to memory we have:

mov total, 2986
mov age, 36h
mov secret_code, 0110100b
mov average, (27/5) + 3

The arithmetic is done by the assembler and anything that is made
up totally of constants is legal. Thus:

mov average, (((64+27)*51 )/(196-82))

is legal but:

mov average, this_year/time

is illegal. The assembler makes either a one byte or a two byte
constant to match the size of the destination. The constants for
"total" and "average" are two byte constants while those for
"age" and "secret_code" are one byte constants. The constants
must be within range, that is -129 is too negative for a byte,
256 is too positive for a byte, -32769 is too negative for a
word, 65536 is too positive for a word. The assembler will give
an error if the constant is out of range.

You can also move a constant to a register:

mov al, 'c'
mov ax, 'c'
mov di, 46280
mov bl, 99

The same rules apply. The constant must be within range and the
assembler will make a constant the same size as the destination
register (one or two bytes). These constants are actually
imbedded in the machine code by the assembler, and are

Lastly, you can move data from one register to another:

mov ax, cx ; from cx to ax
mov ah, bl ; from bl to ah
mov dl, dh ; from dh to dl
mov di, dx ; from dx to di

All this is summarized at the end of the chapter.

It's time for program #4. All this program is going to do is get
input and the move it to different registers. We are still using
temp2.asm. Here's the program:


The PC Assembler Tutor 22

;+ + + + + + + + + + START DATA BELOW THIS LINE

byte_data db ?
word_data dw ?

;+ + + + + + + + + + END DATA ABOVE THIS LINE

;+ + + + + + + + + + START CODE BELOW THIS LINE

call show_regs

call get_hex ; (1)
call show_regs_and_wait

mov dx, ax ; (2)
call show_regs_and_wait

mov byte_data, al ; (3)
mov ch, byte_data
call show_regs_and_wait

mov word_data, ax ; (4)
mov di, word_data
call show_regs

jmp This_is_a_very_long_label_name

;+ + + + + + + + + + END CODE ABOVE THIS LINE

There is a data section in this one, so copy those variables into
your data section. Here is what the program does. (1) it gets a
hex number from the keyboard, (2) it moves the number in ax to
dx, (3) it moves one byte from al to ch via the variable
byte_data, and (4) it moves two bytes from ax to di via

There are two different subprograms - show_regs and
show_regs_and_wait. They do the same thing except that
show_regs_and_wait waits for you to hit the ENTER key before
continuing. The computer works so fast that we wouldn't be able
to see the changes in the screen if we didn't have a way of
pausing. You can use COUNT on the screen to keep track of exactly
where you are in the loop.

Assemble program 4, link it to asmhelp.obj, and watch it work.
There are two things to notice here. First, we are entering a hex
number, but AX is displaying an unsigned number. It is not
self-evident that the unsigned number in AX is the same as the
hex number that you are entering. Secondly, though CH is
changing, there doesn't seem to be any relationship between the
number in AX and the number in CX. We will solve both problems in
the next chapter.

Chapter 3 - ASMHELP.OBJ 23



You can:
(1) move from a register to memory
(2) move from memory to a register
(3) move a constant to memory
(4) move a constant to a register
(5) move from one register to another register

The constants are actual constants which are imbedded in the
machine code.


The normal registers are AX, BX, CX, DX, SI, DI AND BP. AX, BX,
CX, and DX can be divided into AH-AL, BH-BL, CH-CL AND DH-DL. The
'H' is for high and the 'L' is for low.
SP is committed and may not be used.
The segment registers are CS, DS, ES, SS.
The instruction pointer (IP) is not available to you.
The register that holds the flags is manipulated by special
machine instructions.


Call show_regs to see what is in the 8086 registers. Count
increments by one every time you call show_regs.

show_regs_and_wait is the same as show_regs except that it waits
for you to hit the ENTER key to allow you time to look at the

Call set_blue at the outset if you have a color card and a color
monitor and you want to have a blue background.

get_num gets a signed or unsigned number from the keyboard. (1-5
digits). It does no range checking to see whether the number is
too big. All other input routines check to see if a number is too
large for its data size.

get_hex gets a hex number from the keyboard. (1-4 digits)

get_ascii gets characters from the keyboard. (1 or 2 characters)

get_binary gets a binary number from the keyboard (1 - 16 digits)

print_num prints a number as hex, signed, unsigned, char, and

All data transfer to or from ASMHELP.OBJ is via the AX register.