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

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



We got started using the program show_regs in the last chapter,
but we have already run into problems. The hex number doesn't
look the same once we put it in the register - that's because
what we are seeing in the arithmetic registers is an unsigned
number. Also, when we moved a byte from AL to CH, it was clear
that something had moved, but it wasn't clear what the number
was. There are two problems here:

(1) We want to use data in hex, binary, ascii, unsigned and
signed format depending on what we are doing in the program.

(2) Some of the registers can be used as half registers, so
we want a whole register when we need it and a half register
when we need it.

Nooooooo problem. There are eight registers whose formats we want
to be able to change: AX, BX, CX, DX, SI, DI, BP and SP. We need
to give each one a code to tell it what to display. The code is
the following:

signed number 1
unsigned number 2
binary number 3
hex number 4
ascii 5

Also, we need to know whether AX, BX, CX and DX are half or full
registers. The code for that is:

half register 128 (80 hex)
full register 0

We will need to do two things - set up the codes, then tell
show_regs about the code. We'll begin by setting up the codes.

First let's start with SI, DI, BP and SP. They must be full
registers, so the half register information is irrelevant.{1} In
the data section is a set of data starting ax_byte, bx_byte ...
sp_byte. That is where you need to put the code. Don't change the
order of these variables. Just put the correct formatting code in
the appropriate byte.

mov si_byte, 3

will display SI as a binary number.


1 show_regs is very forgiving. It only recognizes half
registers where appropriate, and if you screw up on the format
code, it just makes it an unsigned number.


The PC Assembler Tutor - Copyright (C) 1989 Chuck Nelson

Chapter 4 - SHOW_REGS 25

mov bp_byte, 4

will display BP as a hex number.

mov di_byte, 1

will display DI as a signed number.

That's pretty easy. If you are using AX, BX, CX, or DX as a full
register, they are exactly the same.

mov dx_byte, 5 ; full register, character format
mov ax_byte, 2 ; full register, unsigned format
mov bx_byte, 3 ; full register, binary

If we use half registers we need to pass more information.
show_regs needs to know that it is half registers, not full
registers; it also needs to know what the left format is and what
the right format is. This is easier than it sounds but will take
a little getting used to. The right nibble (half byte) gets the
right format and the left nibble (half byte) gets the left
format. Then you add 128 to the total. This works easily in hex.
13h means that the left half register is (1 = signed) and the
right register is (3 = binary). Then we add (128 = 80h) for a
total of 93h. Here are some more examples. Remember, 8 + 1 = 9, 8
+ 2 = A, 8 + 3 = B, 8 + 4 = C, 8 + 5 = D

C4h ; 80h + 44h left and right are hex
A5h ; 80h + 25h left is unsigned, right is ascii
B1h ; 80h + 31h left is binary, right is signed
D2h ; 80h + 52h left is ascii, right is unsigned
94h ; 80h + 14h left is signed, right is hex

There is a summary at the end of the chapter giving all the
commands and codes for show_regs. It is important to take some
time here and learn to make the registers look the way we want,
because later on we have machine instructions for signed numbers,
for ascii characters, for binary numbers, and you need to see
what the registers look like in the appropriate formats.
Spending a little time right now will save you a lot of time
later on.

If you don't like using hex numbers you can use decimal numbers:

code = type_of_register + left code + right code

where full register = 0, half register = 128d and:


signed 16d 1d
unsigned 32d 2d
binary 48d 3d
hex 64d 4d
ascii 80d 5d

Therefore, left binary, right hex = 128 + 48 + 4 = 180d. Some

The PC Assembler Tutor 26

more examples:

left ascii, right signed = 128 + 80 + 1 = 209d
left signed, right binary = 128 + 16 + 3 = 147d
left hex, right unsigned = 128 + 64 + 2 = 192d

We can put in the code the same way as before.

mov ax_byte, 192d
mov dx_byte, 147d
mov cx_byte, 0D2h
mov bx_byte, 94h

We now have the codes in out program, but show_regs doesn't know
about them. In order to give the information to show_regs, we
call set_reg_style. set_reg_style makes a copy of your
information for use by show_regs. The next time that you call
show_regs, it will use the new register formats. There is a small
problem, however. The information we have is eight bytes long,
and ax is only two bytes long. How do we pass the information?
The answer is: we don't pass the information. Instead, we pass
the address of the information. If you look in the data segment
of temp2.asm, you will see that ax_byte is the first byte of this
data. We pass the address of ax_byte (the first byte) and
set_reg_style knows that that address plus the following 7
addresses have the information that it needs. There is a special
machine instruction for putting an address in a register - it is
LEA or load effective address. It looks like this:

lea ax, ax_byte

This instruction says: put the address of ax_byte in the AX
register. Combined with the call, we have:

lea ax, ax_byte
call set_reg_style

Before we start writing programs with set_reg_style, we will run
a pre-existing program called SETREGS.EXE. Its pathname is
\ASMHELP\SETREGS.EXE. It puts the same (pseudo) random number in
all arithmetic registers except SP, then requests a formatting
code for each register. After cycling through all the registers,
it asks you to press ENTER. It then puts a new random number in
the registers and starts the cycle again. The hex codes are
displayed on the screen before each request. As usual, use
Control-C to exit the program.

Here is what the screen might look like after the first cycle.
The prseudo random number 2571 will be the same, but your
formatting might be different:

Chapter 4 - SHOW_REGS 27

*********************** SCREEN SHOT ***************************
AX +02571 SI +02571
BH 00001010 BL 0B ** DI 02571
CX 0A 0B ** BP 0000101000001011
DH 0A ** DL 0B ** SP 00C4H

CS 0AA4H DS 0A42H ES 0A25H SS 0A35H IP 0115H

x + x + O x COUNT 00009
hex = C0h or 4h; ascii = D0h or 5h
Enter a code for sp.
Enter a one byte hex number 4
Press ENTER to continue


The formats I have used are:
AX full register (signed)
BX half registers (binary, ascii)
CX full register (ascii)
DX half registers (ascii, ascii)
SI full register (signed)
DI full register (unsigned)
BP full register (binary)
SP full register (hex)

Cycle through the registers a couple of times. If you make them
binary, they get longer, if you make them hex or ascii they get
shorter; a sign appears if they are signed, and you can change
from full to half registers for AX, BX, CX and DX.

You will always be able to tell what kind of number show_regs is
printing because (1) a signed number always has a + or - in front
of it, (2) a hex number always has an h after it, (3) a binary
number is 8 digits long for a half register or 16 digits long for
a full register, and (4) an ascii has an asterisk after it. Just
as with print_num, if the ascii character has one of the values
0-32, 127 or 255, it will print a hex number and show a double
asterisk '**' to signal the event. (5) If none of the above is
true, then it is an unsigned decimal number.

If you have a feel for what's happening, it is time to take a
mini-test. This is an untimed test, so just make sure that it is
correct. I'll give you a particular style, and you figure out the
code for that style. The answers are at the bottom of the page.
You don't have to memorize the codes. You should be using the
summary at the end of the chapter for this quiz.

1. full register, binary
2. half register, left ascii, right hex
3. half register, left signed, right unsigned
4. full register, ascii
5. half register, left binary, right ascii
6. half register, left hex, right signed
7. half register, left unsigned, right binary

The PC Assembler Tutor 28

8. full register, hex
9. full register, signed
10. half register, left signed, right binary.

If you feel comfortable with what's going on and are able to do
set the registers with the help of the summary, we are ready to
move on.

Here are the answers.{2}


2 Here are the answers, both in hex and decimal.


1. 3h 3d
2. D4h 212d
3. 92h 146d
4. 5h 5d
5. B5h 181d
6. C1h 193d
7. A3h 163d
8. 4h 4d
9. 1h 1d
10. 93h 147d

These things are slow to calculate. It took me about a minute per
problem to do both the hex and binary.

Chapter 4 - SHOW_REGS 29


The registers may be displayed in signed, unsigned, binary, hex,
and ascii formats. The basic codes for this are:

signed 1
unsigned 2
binary 3
hex 4
ascii 5

In addition you need to add the register type. They are:

full register 0
half register 128d or 80h

For the left half register, we have:


signed 10h 16d
unsigned 20h 32d
binary 30h 48d
hex 40h 64d
ascii 50h 80d

Since the left code is of interest only when the half register
type is being used, we simply add 80h and come up with:


signed 90h 1h
unsigned A0h 2h
binary B0h 3h
hex C0h 4h
ascii D0h 5h

Or we add 128d and have:


signed 144d 1d
unsigned 160d 2d
binary 176d 3d
hex 192d 4d
ascii 208d 5d


Formats are set by calling set_reg_style. The address of ax_byte
must be in AX. The standard assembler instructions for this are:

The PC Assembler Tutor 30

lea ax, ax_byte
call set_reg_style

set_reg_style makes a copy of your format data. It changes
nothing on the screen. The next time that you call show_regs, it
will use the new formatting data.

The correct order for the data in the data segment is:

ax_byte, bx_byte, cx_byte, dx_byte, si_byte, di_byte, bp_byte,
sp_byte. They are, of course, all byte sized data.