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

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



It is now time to start writing assembler code. One of the
problems with writing in assembler is that there is no way to get
input into the program or output from the program until you are
very far along with learning assembler language. This is a
Catch-22 situation. You can't learn assembler easily without
access to input and output, and you can't write i/o routines till
you know assembler.{1} Help is at hand. Included on this disk is
a file called asmhelp.obj. It is actually a series of programs
that will allow you to get input from the keyboard and print
output to the screen. It has some other features which will be
explained later.

The second problem at the start is that every assembler program
has a lot of overhead. These are standard instructions and
formats that you need to get the program to work AT ALL. This
disk contains templates that contain all the overhead, so to
write a program you just make a copy of the template and enter
the code and data at the appropriate place. By the end of this
sequence of lessons, you will know how to make templates yourself
and know the meaning of each word in the template. For now, you
have to have faith that what is written is necessary, and that
you will learn the meaning of everything later.

Let's start. At the end of this chapter is the template we will
use for now - temp1.asm. These templates are in the subdirectory

Let's call the first program prog1.asm (very original). All
programs in assembler must have the file extension .asm so make a
copy by giving the command:

>copy \template\temp1.asm prog1.asm

You are now ready to enter code. Open up prog1.asm with your
editor, and take a look at it. It should look the same as

Where it says "put name of program here" - that is for your
personal use so you can see the program name while in the editor.
The assembler ignores everything after a semicolon. All the lines
that start with a semicolon are there for visual separation or
for comments. The lines with asterisks separate segments. Yes,
the assembler is going to make this program into three segments.
You should put all code between the line labeled "START CODE

1 Just to give you an idea of how contradictory the
situation is, asmhelp.obj was written in assembler language and
consists of about 3500 lines (that's about 50 pages), yet you
need to be using it from day one.


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

The PC Assembler Tutor 2

Later you will get more flexibility.

Also notice the lines starting with the word EXTRN. Those lines
tell the assembler that the subroutines (such as print_num) are
in a different file and must be found when this program is
linked. The assembler enters each EXTRN name in a list and
records each place that an EXTRN subroutine is requested. It is
possible that one of these subroutines is never requested. That's
fine. However, every one of these subroutines must be present at
link time or you will get a link error. This is true even if the
subroutine is on the list but never requested.

Since the overhead is so long, and I am so lazy, the template
will never be included in the description of the program. What
you will get is the name of the template, then any data you need,
then the code. It will look like this:

the data is written here

the code is written here

If there is no data, no data section will be included. If there
is data, it should be written in the segment named DATASTUFF
between the lines "START DATA..." and "END DATA ...". The code
should be written between the lines that say "START CODE ..." and
"END CODE ...".

For our first program, the description will look like this:


call get_num
call print_num
jmp first_label


That's all we need. If we needed to write all the overhead
(starting with the line "main proc far") we would have:

main proc far
start: push ds
sub ax, ax
push ax

mov ds, ax

; + + + + + + + + + + +

Chapter 1 - Some Simple Programs 3

call get_num
call print_num
jmp first_label

; + + + + + + + + + + +



You can see that a simple four line program has blossomed into a
monster. I'm assuming some intelligence on your part. Until
further notice, the code goes between the "START CODE' and the
"END CODE" lines and the data goes in the DATASTUFF segment
between the "START DATA" and the "END DATA" lines.

It's time to type in the program listed above. Be careful when
you type. When you are done I'll explain it.

In assembler we need a way to label different spots in the code.
We use labels. A LABEL is a name (at the beginning of a line)
which is immediately followed by a colon. A label doesn't
generate any code. The assembler merely keeps track of where the
label is for future use. The label we are using is named

The CALL instruction tells the assembler to call the subroutine
listed after the call.{2} We are calling two subroutines; first
get_num which gets a number, then print_num, which prints a
number in a variety of styles.

Finally, JMP tells the assembler that you want to jump to the
label listed after it. It is the same as GOTO in BASIC.

If you look at the program, you will notice that we have an
infinite loop. It was designed that way. It takes a fair amount
of code to exit gracefully, so we will always exit ungracefully.
When you are tired of the program, simply press Control-C. That
should get you out. That way you can try out something an
indefinite number of times, and when you have finished you can
press CTRL-C to quit the program.

One warning about machine language before we start. There is no
safety net, so before you start a machine language program, make
sure all files are closed (i.e. that you have no other programs
in memory). We will NEVER open a file in one of our programs.

2 I am using the words subroutine, routine, program and
procedure (the technical word) interchangebly throughout the
book. A program is actually a group of one or more procedures,
but I'm not going to be too strict about it. Context should tell
whether we are talking about a single procedure or a whole

The PC Assembler Tutor 4

Your programs are almost certain to wind up in zombie space from
time to time. If that happens, your choices are (1) hit CTRL-C.
If that doesn't work, then (2) hit CTRL-ALT-DEL. As a last
resort, you can (3) hit a reset button or shut the machine down.

For that reason, memorize this mantra: BACKUP YOUR PROGRAMS AND

Double check that you have typed in the assembler code correctly.
Now it's time to assemble it. I am assuming that you have the
Microsoft assembler.{3} Type:

>masm prog1 ;

The first thing you will see is the copyright notice:

Microsoft (R) Macro Assembler Version 5.10
Copyright (C) Microsoft Corp 1981, 1988. All rights reserved.

The file extension .asm is unnecessary; it's understood.
The semicolon is to speed things up. If you don't use it, the
assembler will ask you if you want to change any of the default
choices. If you type just masm:


then you need to give the name of the assembler text file on the
first line:

Source filename [.ASM]: prog1
Object filename [prog1.OBJ]:
Source listing [NUL.LST]:
Cross-reference [NUL.CRF]:

but press ENTER for the other options. If you type masm prog1:

>masm prog1

You don't want to change any of the default settings:

Object filename [prog1.OBJ]:
Source listing [NUL.LST]:
Cross-reference [NUL.CRF]:

When the assembler asks you about options, hit the ENTER key.

If you have made any errors, the assembler will tell you which
line they are on and give you a description of the problem. Make
a hard copy of them on the printer, then use your editor and find
the line. Unfortunately, at this stage of the game, it will be

3 If you are using A86, then consult A86.APP. If you are
using Turbo Assembler, then consult TASM.APP. They are both
located in the \APPENDIX subdirectory on disk 3.

Chapter 1 - Some Simple Programs 5

very difficult for you to figure out what the problem is. You
will have to struggle through the first 4 or 5 programs before
things start getting easier. All the programs on these disks have
been compiled on a Microsoft v5.1 assembler. They have assembled.
They have been run, and they work. Don't tamper with the template
and copy the code exactly and everything should work.

If you haven't made any errors, the assembler will say:

0 Warning Errors
0 Severe Errors


The assembler has given you back another program named prog1.obj
- the same name with the extension .obj. I am assuming that you
have all used the linker with compiled programs. If you haven't,
you may be getting in over your head by using machine language.
All the extra subroutines are in a program called asmhelp.obj.
Its pathname is \asmhelp\asmhelp.obj. You want to put it in the
root directory of your current drive. In the whole book, we will
assume that its pathname is:


If you put it somewhere else, you will have to modify the
pathname whenever it appears. Link the two modules by writing:

>link prog1+\asmhelp ;

The copyright notice will appear:

Microsoft (R) Overlay Linker Version 3.61
Copyright (C) Microsoft Corp 1983-1987. All rights reserved.

This time the file extensions are understood to be .obj. The
semicolon is to avoid having to make default choices. If you


then you need to put the module names after the first prompt:

Object Modules [.OBJ]: prog1+\asmhelp
Run File [PROG1.EXE]:
List File [NUL.MAP]:
Libraries [.LIB]:

but press ENTER for the other choices. If you type:

link prog1+\asmhelp

You need to do nothing extra:

Run File [PROG1.EXE]:

The PC Assembler Tutor 6

List File [NUL.MAP]:
Libraries [.LIB]:

When the linker asks for choices, simply press the ENTER key.

The linker gives the executable file the name of the first object
file on the line, so you should always put your program first and
asmhelp.obj second.

If there are no errors, you are ready to go. If there are errors,
once again, they will be very difficult to trace. Go back and
check everything from the beginning.

You are now ready to run the program. Type:


The program will start. The first thing you will see is a
copyright notice.

The PC Assembler Helper Version 1.0
Copyright (C) 1989 Chuck Nelson All rights reserved.

It appears the first time you call a subprogram in the module

The program will request a number. Give it any legal signed or
unsigned number. It should be no longer than 5 digits. Press
ENTER, and it will display the possible ways that that number can
be thought of by the computer.

Enter any decimal number 4410
113AH +04410 04410 11 : ** 0001000100111010

Enter any decimal number 30486
7716H +30486 30486 w 16 ** 0111011100010110

If the signed or unsigned number doesn't look the same as what
you entered, then the number you entered is too big for a 16 bit
computer. For signed numbers, the limits are +32767 to -32768 and
for unsigned numbers, the limits are 0 to 65535.

Enter any decimal number -64661
036BH +00875 00875 03 k ** 0000001101101011

Enter any decimal number 94547
7153H +29011 29011 q S * 0111000101010011

Lets look at the numbers. Each type of output is labeled. After a
hex number, there is an 'H' and after the characters, there is a
'*'. This is always true. Every time you print a hex number,
there will be an 'H', and every time you print a character, there

Chapter 1 - Some Simple Programs 7

will be a '*'. This is so you will always know what is being
printed. Also notice that a signed integer ALWAYS has a sign and
an unsigned integer NEVER has a sign.

Not all characters are visible. Ascii 0 - 32 are invisible (32 is
a blank). On the PC, ascii 33-255 are visible, but ascii 127 and
ascii 255 are problematic. Therefore, if the ascii code is 0-32,
127 or 255, that character will be printed as a hex number, not a
character, and print_num will signal the event by printing a
double asterisk '**' instead of a single one. This has happened
in the first two examples. ( 11 : ** ) and ( w 16 ** ). The
first one is the hex number 11 followed by the character ':' and
the second one is the character 'w' followed by the hex number
16. Both are signalled by the double asterisk '**' instead of the
single asterisk '*'.

Do a few examples. When you are done looking at the numbers,
press CTRL-C and you will exit the program.

Enter any decimal number ^C


The second program is almost the same as the first one. The
program takes input from the keyboard and displays it in a
variety of styles. This time, however, it is going to ask for
different inputs: ascii, hex, binary and decimal. If you make an
error in the input, the subroutine will prompt you again for the
input. Here's the program:

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

call get_num ; 1 to 5 digit signed or unsigned
call print_num

call get_ascii ; 1 or 2 characters
call print_num

call get_binary ; a 1 to 16 bit binary number
call print_num

call get_hex ; a 1 to 4 digit hex number
call print_num

jmp first_label

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

The things to the right of the semicolons are comments. You do
not need to type them in if you don't want to. Once again,
assemble the program. (There should be no warning or severe
errors. If something is wrong, it is most likely a typing error.)
Then link it with asmhelp.obj. Remember - your program should be

The PC Assembler Tutor 8

the first one listed.{4}

If all is well, run the program. It will ask you for a number
(that is a signed or unsigned number), ascii characters, a binary
number, and a 4 digit hex number (0-9,A-F).

Enter any decimal number 27959
6D37H +27959 27959 m 7 * 0110110100110111

Enter one or two ascii characters $%
2425H +09253 09253 $ % * 0010010000100101

Enter a two byte binary number 0101111001100010
5E62H +24162 24162 ^ b * 0101111001100010

Enter a two byte hex number 784d
784DH +30797 30797 x M * 0111100001001101

Once again, this is an infinite loop, so in order to quit, you
need to hit CTRL-C.

The purpose of these first two programs is to remind you that the
computer doesn't care whether you think you are storing binary
numbers, characters, hex numbers, signed numbers or unsigned
numbers. They all wind up in the computer as a series of 1s and
0s, and you can use these 1s and 0s any way you like. It's up to
you to keep track of them.

If you feel comfortable with the way we are writing, assembling
and linking programs, you are ready to start looking at the 8086


4 For your convenience, there is a batch file on the disk
called asmlink.bat. Its pathname is \asmhelp\asmlink.bat. It is
one line long and looks like this:

link %1+\asmhelp ;

If you use this batch file, you will never have an order problem.
If your file is named myfile.asm, then type:

>asmlink myfile

Chapter 1 - Some Simple Programs 9

; TEMP1.ASM The first assembler template

; put name of program here

; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

dw 100 dup (?)

; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

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

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

; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

EXTRN print_num:NEAR , get_num:NEAR
EXTRN get_ascii:NEAR , get_hex:NEAR , get_binary:NEAR


main proc far
start: push ds ; set up for return
sub ax,ax
push ax

mov ds,ax

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

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


main endp

; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

END start

The PC Assembler Tutor 10


CALL calls a subroutine.

call get_num

JMP jumps to the indicated label.

JMP label47

A label is a name at the beginning of a line which is
followed by a colon. It is used to mark a spot in the


There are three different things which will be mentioned from
time to time, so it's best to define them now.

ASSEMBLER INSTRUCTIONS (CODE) is the text that you type in and
give to the assembler.

MACHINE CODE is the code that the assembler generates. After some
adjustment by the linker, it is readable by the 8086. It is the
actual code that controls the program.

MICROCODE is the code that is imbedded in the 8086 itself. Each
instruction has its own set of mini instructions within the 8086.
This is the MICROCODE.