Socha, Norton-Assembly Language for the PC-3rd Edition-1992
April 28, 2017 | Author: Mostitt | Category: N/A
Short Description
Assembly programming...
Description
John Socha and Peter
N
QRTHE THIRD EDITION •Harness the power of the
microprocessor •Build real-world
Disk Inside
80x86
.
"
-
.^
'"
programs, including a
general-purpose7full-screen disk editor
•Add compact assembly code C-i-i-
to
your
C and
programs
•Use assembly code
Disk includes
examples
in
all
the
protected-mode and
code
book
plus
more than 30 valuable, time-saving assembly routines for your
in
the
C-I--H
C and
programs
Windows programming •Master advanced techniques such as step-
wise refinement and modular design ..Ate-^M^;
Assembly Language for the
PC,
Third Edition
John Socha
and Peter Norton
Brady Publishing
New
York
London
Toronto
Sydney
Tokyo
Singapore
© 1992 by John Socha and Peter Norton
Copyright
All rights reserved, including the right of reproduction in
whole or
in part in
any form.
Brady Publishing
A Division of Prentice 1
5
Columbus
Hall
Computer Publishing
Circle
New York, NY
10023
ISBN: 1-56686-016-4 Library of Congress Catalog No.: 92-44830
The rightmost number
Printing Code:
rightmost single-digit
shows that the
first
number is the year of the book's printing; the number of the book's printing. For example, 92-1 book occurred in 1992.
double-digit is
the
printing of the
4 3
95 94 93
Manufactured
in the
United States of America
Limits of Liability and Disclaimer of Warranty: The author and publisher of this book have used their best efforts in preparing efforts include the
this
book and the programs contained
in
it.
These
development, research, and testing of the theories and programs to
determine their effectiveness.
The author and
publisher
make no warranty of any
kind,
expressed or implied, with regard to these programs or the documentation contained in this
book. tial
The author and
damages
in
publisher shall not be liable in any event for incidental or consequen-
connection with, or arising out
of,
the furnishing, performance, or use of
these programs.
Trademarks: Most computer and software brand names have trademarks or trademarks.
The
individual trademarks have not been listed here.
registered
About the Authors PC industry for his writing and his software prodthe early days of the IBM PC, he wrote a column for the now defunct
John Socha is known ucts. In
magazine Sofialk
in
in the
which he published such programs
screen saver) and Whereis (the
the demise ofSofialk,
program
first
John concentrated on
as
to find files
ScrnSave (the
on hard
first
disks). After
and
finishing his Ph.D. in Physics
The Norton Commander, which became a best-selling software product. He is also the coauthor of the best-selling book PC-World DOS 5 Complete Handbook and the author of Learn Programming znd Visual Basic 2 with writing
John Socha. John grew up
in Wisconsin, earned a B.S. degree in Electrical
En-
gineering from the University of Wisconsin, and an M.S. and a Ph.D. in
Ap-
plied Physics
from Cornell University.
He now runs a software company called
Socha Computing that develops Windows and Macintosh
utility
software in
Kirkland, Washington.
Entrepreneurial software developer Peter Norton
dozen technical books. His
first
is
the author of more than a
book, the best-selling
classic Inside the
IBM
PC, was published in 1 983, and was followed later in the year by another Brady book, his immensely popular guide to
Born
in
1943 and
raised in Seattle,
DOS.
Washington, Mr. Norton attended Reed
College in Portland, Oregon, where he majored in physics and mathematics.
He completed his education at the
University of California at Berkeley where
he received a Bachelor of Arts in mathematics. During the Vietnam served in the U.S.
Army and
War
he
taught emergency medicine to combat medics.
He received a priestly teaching certificate after studying for five years in a Zen Buddhist monastery. Mr. Norton held a variety of positions in the computer industry before he created the
subsequently founded his
Norton
Utilities soft^vare
own company,
Peter
develop and market his software. During the
program
in 1982.
Norton Computing,
last
He
Inc., to
decade, he has written
many
popular columns for computer magazines. In 1990 he sold his company to
Symantec Corporation and devoted himself
to the
Norton Family Founda-
tion, a fiind that provides financial assistance to arts organizations in the
Angeles
and
area.
their
Los
He currendy lives in Santa Monica, California, with his wife Eileen
two young children Diana and Michael.
Credits Publisher Michael Violano
Managing Editor Kelly D.
Dobbs
Editor Tracy Smith
Production Editors Bettina Versaci
Tom Dilbn
Developmental Editor Perry King
Editorial Assistant Lisa Rose
Book Designer Michele Laseau
Cover Designer
HUB Graphics Production
Team
Katy Bodenmiller Christine
Cook
Lisa Daugherty
Carta Hall-Batton
Dennis Clay Hager
Howard Jones John Kane Loren Christopher Malloy
Sean Medlock
Tim Montgomery Roger Morgan
Linda Quigley Michelle Self
Susan Shepard
Angie Trzepacz
Contents Introduction
Part 1
I
xv
Machine Language
1
Learning Debug and Computer Arithmetic Topics Covered
3
A Brief History of Intel Microprocessors
4
Counting the Computer
Way
5
Counting with Hexadecimal Numbers
5
Using Debug
6
Doing Hex Arithmetic
7
Converting Hexadecimal to Decimal
9
Hex Numbers
12
Five-Digit
Converting Decimal to Hex
13
Working with Negative Numbers
15
Bits, Bytes,
Words, and Binary Notation
Two's Complement
—
^An
Odd
Sort of Negative
Summary 2
Doing Arithmetic with
Using Registers
Using
Memory
the 80x86
Negative
3
Number
19
24 25
as Variables
in the
80x86
Addition, 80x86 Style Subtraction,
17
21
Topics Covered
i
2
80x86
Numbers
27 30 32
Style in the
26
80x86
33
Bytes in the 80x86
34
Multiplication and Division, 80x86 Style
35
Summary
38
Printing Characters Topics Covered
— Using DOS Functions Programs— INT 20h
40 41
INT
42
Exiting
44
Assembly Language
for the
PC, Third Edition
—
Putting the Pieces Together
^A
Two-Line Program
Entering Programs
46
Moving Data into
47
Registers
Writing a String of Characters
50
Summary
52
4 Printing Binary Numbers
54
Topics Covered Rotating
55
Numbers through
Adding the Carry Flag Looping
— Repeating
to a
the Carry Flag
Number
Stepping over INTs with the Proceed
59
Number
61
Command
63
Summary Printing
63
Numbers
in
Hex
67
Comparing Numbers
68
Using the Status
Using
Using Rotate Using
Bits
68
—Conditional Jumps
CMP to Compare Numbers
Printing a Single
Hex Digit To Get the Upper Nibble
AND to Isolate the Lower Nibble
Putting
It
All Together
Summary Reading Characters
Reading
70 70 71
73 75
77 11
Topics Covered
One
Character
Number Two-Digit Hex Number
80 81
82
Reading a Single-Digit Hex
83
Reading a
84
Summary 7 Using Procedures to Write Reusable Code
VI
66
Topics Covered
Other Status Flags
6
56 58
a Block of Code
Building a Program to Display a Binary
5
45
85
86
Topics Covered
87
Writing Procedures
88
1
Contents
How CALL Works: The Stack and PUSHing and POPping Data Reading Hex Numbers with More Summary
Part
II
8
Return Addresses
91 Class
Assembly Language Welcome
to the Assembler
101
Building a Program without
Debug
Writestr in
106
Debug
Using Comments for
109 1 1
9 Writing Procedures in Assembly Language
11
108 108
Code
Summary
10
102 105
Linking Your Program
Using Labels
96
100
Creating Source Files
at
94
99
Topics Covered
Looking
90
114
Topics Covered
115
The Assembler's Procedures The Hex-Output Procedures The Beginnings of Modular Design
116
A Program Skeleton
123
Summary
124
118
122
126
Printing in Decimal Topics Covered
127
Reviewing the Conversion to Decimal
128
Some Tricks and Shortcuts The Inner Workings of WRITE_DECIMAL Summary
131
135
138
Segments Topics Covered
How Memory Is
133
139
Divided into Segments
The Stack The Program Segment
140
144 Prefix (PSP)
146
Vll
Assembly Language
for the
PC, Third Edition
DOSSEG Directive NEAR and FAR CALLs
The
More on
12
13
the
INT
147 149 152
Instruction
Interrupt Vectors
153
Summary
154
Course Corrections
—How
to Build
Dskpatch
Topics Covered
157
Disks, Sectors, and So Forth
158
The Game Summary
161
Plan for Building Dskpatch
162
Modular Design
—Building Programs
in Pieces
165
Separate Assembling
166
The Three Laws of Modular Design Using the Programmer's Workbench Using PWB's Pull-Down Menus
170
174
Program
176
List
177
PWB
178
Jump
179
to Definitions
Loading the Program
181
List
Summary
181
Dumping Memory
184
Topics Covered
185
Using Addressing Modes
to Access
Memory
186
Using the Data Segment
189
Base-Relative Addressing
191
Setting
DS
to Point to
Adding Characters
Dumping 256 Summary
Vlll
175
BuildingTEST.EXE Editing Files in
15
164
Topics Covered
Setting the
14
156
your Data Segment
to the
Dump
Bytes of Memory
Dumping a Disk Sector
193
194 197
202
204
Topics Covered
205
Making
206
Life Easier
Contents
Format of the
16
NMake
207
File
Patching up Disp_sec
208
Reading a Sector
210
The .DATA? Summary
215
Directive
216
Enhancing the Sector Display Topics Covered
219
Adding Graphics Characters
220
Adding Addresses
222
to the Display
Adding Horizontal Lines
227
Adding Numbers
232
to the Display
Summary Part
III
17
234
The IBM PC's The
ROM BIOS
ROM BIOS Routines
The
239
ROM BIOS Display Routines
240
Clearing the Screen
244
Moving
246
the Cursor
248
Rewiring Variable Usage
Writing the Header
'.
Summary
252 256
The Ultimate WRITE_CHAR
258
Topics Covered
259
A New WRITE_CHAR
260
Clearing to the
End of a Line
Summary 19
237 238
Topics Covered
18
218
The Dispatcher
264
267
268
Topics Covered
269
Building a Dispatcher
270
Reading Other Sectors
277
Philosophy of the Following Chapters
281
IX
Assembly Language
20
for the
PC, Third Edition
A Programming Challenge
282
Topics Covered
283
The Phantom Cursors
284
Simple Editing
Other Additions and Changes
21
The Phantom Cursors
286
288 289
The Phantom Cursors
290
Changing Character Attributes
296
Summary
297
300
Topics Covered
301
Moving
302
the
Phantom Cursors
Simple Editing
306
Summary
310
Hex and Decimal Input
312
Topics Covered
313
Hex Input
314
Decimal Input
323
Summary
327
24 Improved Keyboard Input
328
Topics Covered
329
A New READ_STRING
330
User vs Programmer Friendly
337 342
Summary 25
Dskpatch
Topics Covered
22 Simple Editing
23
285 to
In Search of Bugs
344
Topics Covered
345
Fixing
DISPATCHER
Summary
26 Writing Modified Sectors
346 348
350
Topics Covered
351
Writing to the Disk
352
Contents
More Debugging Techniques Building a Road Map
Down
Tracking
354 355
Bugs
358
Source- Level Debugging
360
CodeView Turbo Debugger
Microsoft's
361
Borland's
365
Summary
369
27 The Other Half Sector
370
Topics Covered
371
Scrolling
by Haifa Sector
372
Summary Part IV
375
377
Advanced Topics
28 Relocation
378
Topics Covered
Writing
379
COM Programs
380
Using Full Segment Definitions
380
Relocation
381
COM vs EXE Programs
386
29 More on Segments and
ASSUME
390
Topics Covered
391
Segment Override
392
Another Look
at
ASSUME
394
Summary
30
AVeryFastWRITE_CHAR
396
Topics Covered
397
Finding the Screen Segment
398
Writing Directly to Screen
31
395
Memory
400
High-Speed Screen Writing
403
Summary
411
Using Assembly Language in
C and C++
Programs
412
Topics Covered
413
A Clear Screen for C
414 XI
Assembly Language
for the
PC, Third Edition
Using Clear_screen
One
Passing
in
C++
418
420
Parameter
426 428
Passing Multiple Parameters
Returning Function Values
Memory Models
429
NEAR and FAR Functions Working with NEAR and FAR Data
432
Writing General-Model Procedures
436
Using Other Writing
Summar)^ on Writing C/C++ Procedures
432 in
Assembly
Writing In-Line Assembly Code
441
Summary on
443
In-Line Assembly
444
DISKLITE,
a
RAM-Resident Program
446
Topics Covered
447
RAM-Resident Programs
448
Intercepting Interrupts
448
Disklite
450
33 Protected-Mode and Windows Programming
Is
Protected
458 459 460
Topics Covered
What
Mode?
A Brief History of the 80x86
460
Memory
461
How Descriptor Tables Work
463
Addressing Extended
Working
in
Windows
Validating Pointers,
Determining the
The
465
Pan
Size of
1
Segments
465
467 471
32-Bit Registers
Validating Pointers,
Pan
II
472 478
Simimar)^
34 Closing Words and Bibliography
480
Topics Covered
481
80x86 Reference Books
482
DOS
XII
440
Using Far Data
Summary^
32
439
and
ROM BIOS Programming
483
Contents
RAM
Resident Programs
Advanced
A
B
DOS
Programming
483
484
Windows Programming
484
Software Design
485
Other References
485
Guide
to the
Disk
486
Topics Covered
487
Chapter Examples
488
Advanced Version of Dskpatch
489
DISKLITE Program Windows Code C/C++ Libraries
492
Listing of Dskpatch
494
492 492
Topics Covered
495
Descriptions of Procedures
496
CURSOR.ASM
496
DISK_IO.ASM
496
DISPATCH.ASM
497
DISP_SEC.ASM
497
DSKPATCH.ASM EDITOR.ASM
498
KBD_IO.ASM
498
PHANTOM.ASM
499
VIDEO_IO.ASM
500
Dskpatch Make
Program
501
File
Dskpatch Linkinfo
File
Listings for
498
Dskpatch Procedures
502 503
CURSOR.ASM
503
DISK_IO.ASM
507
DISPATCH.ASM
510
DISP_SEC.ASM
512
DSKPATCH.ASM EDITOR.ASM KBD_IO.ASM
519
PHANTOM.ASM
531
VIDEO IO.ASM
537
520
522
Xlll
Assembly Language
for the
C C/C++
D
PC, Third Edition
Libraries in
Assembly
Topics Covered
547
Descriptions of Procedures
548
SOCHALIBJNC
548
MAKEFILE CURSOR.ASM FASTWRIT.ASM
548
HARDWARE.ASM
551
KBD_IO.ASM
551
MOUSE.ASM
552
548 549
Makefile
553
SOCHALIBJNC CURSOR.ASM
554
FASTWRIT.ASM
561
HARDWARE.ASM
577
KBD_IO.ASM
580
MOUSE.ASM
584
555
592
Miscellaneous Tables Topics Covered
593
Table D-1 ASCII Character Codes
594
Table D-2 Color Codes
598
Table D-3 Extended Keyboard Codes
598
Table D-4 Table of Addressing Modes
INT lOh D-6 INT I6h D-7 INT 21h
599
Table D-5
Functions
600
Table
Functions
603
Functions
604
Table
Table D-8 Sector Read/Write Fimctions
Index
XIV
546
606
609
Introduction Why Learn Assembly Language? There are now more reasons than ever
to learn
grammers who only use a high-level language
assembly language. Even pro-
like
C/C++
or Pascal can benefit
from learning assembly language.
When we wrote
the
first
and companies were
edition of this book, several years ago,
actually writing entire
For example, Lotus 1-2-3 before
release
programs
in
programmers
assembly language.
2 was written entirely in assembly lan-
guage. These days, very few programs are written entirely in assembly language.
Even 1-2-3 has now been rewritten
on
to
C++, which
guage. So
and many programmers
in C,
a very powerful descendent of the
is
if people are
why would you want
C
are
moving
programming
lan-
not writing large programs in assembly language, then
to learn
Knowing assembly language
and use assembly language?
will
make you
a better programmer, even if you
never actually write any assembly-language subroutines or code for your pro-
grams.
Many of the
idiosyncrasies
you
will find in
have their roots in the microprocessor and really learning
puter. This insight should
make many of the
-32,768
For example, you
to 32,767,
and you
Assembly language programs In relation to est
all
artifacts
why an
will learn all
design.
When
It
you
learn
of computer languages
about bytes, words, and segments.
PC compatible computer.
are at the heart of any
takes
you
integer has a value range of
other programming languages, assembly language
common denominator.
level
will see
its
or Pascal programs
about the architecture of your com-
assembly language, you are
clear to you.
C/C++
closer to the
is
the low-
machine than the higher-
languages do, so learning assembly language also means learning to
understand the 80x86 microprocessor inside your computer.
This knowledge about the microprocessor Microsoft Windows,
as
you will
see in
is
also very useful in the
world of
Chapter 33, which discusses protected-
mode and Windows programming. You will learn about some features of Windows programming that you probably won't find in any other book. This is
because there are programming techniques that you can do and learn about
in assembly language that
language.
you would not normally
learn about in a high-level
Assembly Language
for the
PC, Third Edition
At some time or other most programmers write or modify some assembly language code. This
common
is
even true for Microsoft
reason to use assembly language
C/C++ and
Pascal compilers are very
fast;
is
Windows
programs.
The most
Computers, modern
for speed.
compiled code runs very quickly.
But there are times when even compiled C/C++ or Pascal code won't be enough. Very often
in these cases
you can write
a small
fast
amount of assembly-
language code to perform the work in the inner loop.
Compilers have also improved significantly since we wrote the this
first
edition of
book. Years ago you had to use an assembler, such as Microsoft's Macro
Assembler, to add assembly-language code to your programs. But almost
all
compilers these days support in-line assembly, which allows you to add a few lines
of assembly-language code directly to your program, between
lines
of
much easier to use small amounts of assembly language in your programs. You will learn how to use in-line assembly C/C++ in
or Pascal code. This makes
it
Chapter 31.
There are
also other cases
which require programmers
to write larger
of code in assembly language. If you are writing a device driver for
Windows, you
will
or almost any other operating system (except for
amounts
DOS
or
Windows NT),
probably have to write the device driver in assembly language. For
Windows has a very powerful mechanism called a Virtual Device known as a VxD) that allows you to alter the way devices work inside Windows for all Windows and DOS programs running imder Windows. These VxDs must be written in assembly language. example,
Driver (also
The Approach
We Use
Like most introductory books on assembly language programming, this book
how to use the instructions of the 80x86 microprocessor. But we much farther and cover advanced vcvzicndX that you will find invaluable when you start to write your own programs. shows you
will
By
go
the time
you
finish reading this book,
you
will
know how
to write large
how to use assembly language in your C/C++ programs and Windows programs. Along the way, you will also learn many assembly language programs and
techniques that professional programmers use to
XVI
make
their
work
simpler.
Introduction
These techniques, which include modular design and step-wise refinement, will double or triple your programming speed and help you write more readable and reliable programs.
The technique of step-wise
refinement, in particular, takes a lot of the
work
out of writing complex programs. If you have ever had that sinking, where-
you
do-I-start feeling,
and natural way
We will
will find that step-wise
to write programs. It
also try to
is
refinement gives you a simple
also fiin!
show you how comments can help you write better procomments explain why you. are doing something, rather
grams. Well-written
than what you are doing. In well-written code
code
is
doing, but
This book
is
not
it
all
certainly
theory.
Disk Patch), and you
may not
be clear
will find
it
have an opportunity to see
Dskpatch
is
should be obvious what the
We will also build a program called Dskpatch (for usefiil for several reasons. First,
step-wise refinement and modular design at will
it
why you are doing something.
why
work
you
will see
program and you
in a real
these techniques are so useful. Also,
a general-purpose, fiill-screen editor for disk sectors
—one
that you
can continue to use both in whole and in part long after you have finished
with
this
book.
Book
Organization of This
We have chosen an approach to teaching assembly language that we think will get
you up
details.
to speed as quickly as possible without
With
approach you
this
instructions before
you have
will
to write small
programs in
about the 80x86
lot
to learn about using an assembler.
chosen to write most of the sample programs for
The
overwhelming you with
be able to learn a
DOS because
We have also
it is
a lot easier
DOS than to write the same program for Windows.
concepts and techniques you learn will also apply to programs you write
in other operating
might read Parts This book or not you
is
I
environments, so
and
II,
if you
want
to
program
for
Windows, you
then skip to Chapters 31 and 33.
divided into four parts, each with a different emphasis.
know
Whether
anything about microprocessors or assembly language, you
will find sections that are
of interest to you.
XVll
Assembly Language
Part
I
for the
focuses
on
PC, Third Edition
the
80x86 microprocessor. You
will learn the mysteries
and machine language. Each of the seven chapters contains a wealth
bits, bytes,
of real examples that use a program called Debug, which comes with
Debug your
will allow us to
PC
of
as
it
runs
DOS.
look inside the 80x86 microprocessor nestled deep in
DOS.
Part
I
assumes only that you have a rudimentary
knowledge of programming languages and know
how
to
work with your
computer. Part
Chapters 8 through 16, moves on to assembly language and
II,
how
to
The approach is not complicated, and rather assembler itself, we will concentrate on a set of
write programs for the assembler.
than cover assembler
We will then
to write useful programs.
use the assembler to rewrite
move on
in order for
programs. clear
the details of the
all
commands needed
some of the programs from
to begin creating Dskpatch.
you
to learn
how
Part
I,
and
We will build this program slowly,
to use step-wise refinement in building large
We will also cover techniques like modtilar design that help in writing
programs. As mentioned, these techniques will simplify programming
by removing some of the complexities normally associated with writing assembly-language programs. In Part
III,
which includes Chapters 17
more advanced features found sor
and
clearing the screen.
in PCs.
to 28,
we
will concentrate
on using
These features include moving the cur-
We will also discuss techniques for debugging larger
assembly-language programs. Assembly-language programs grow quickly and
can easily be two or more pages long without doing very
be longer). Even though
we will
few pages, you
larger than a
much (Dskpatch will
use these debugging techniques on programs
also will find
them
useful with small programs.
Pan IV covers a number of advanced topics that will be of interest to you when you Stan to write real programs. The first two chapters cover details about COM programs, memory, and segments. Then there is a chapter on writing directly to screen memory for very fast screen displays. Next, there is a chapter on writing assembly-language procedures that you can use in your C/C++ programs. You will learn
for
how to write general-purpose routines entirely in assembly language will also learn how to use in-line assembly.
any memory model, and you
There
is
Next is
a lot
a chapter
DISKLITE XVlll
of material in
this chapter that
is
very difficult to find elsewhere.
on RAM-resident programs, complete with
a
program
called
that adds a disk light to your screen. Finally, you will find a
Introduction
Windows programming that will show you about the way Windows works on an 80386 or better
chapter on protected-mode and
some
interesting details
microprocessor.
What
Is
on the Disk?
The disk included with find in this
book
this
book contains most of the code examples you will
in a directory called
CHAPS. We
vanced version of Dskpatch in a directory called
have included a more ad-
ADVANCED. Appendix A
discusses both of these directories.
Appendix B contains
for
C and C++
The
a complete listing of the
book. Appendix
in this
set
programs that
of libraries for
you'll find
on the disk
is
the code that
Norton Commander, which means we had thors
who
at the
back of this book.
C and C++ programs allows you to write quickly to the
screen and support a mouse. This code
also
Dskpatch program we will build
C contains listings for some general-purpose libraries
we used
to write the
to deal with issues that other au-
have not written commercial software have never encountered.
means
that these libraries have been thoroughly tested
thousands of users. All of this code book, and you'll find complete
is
It
by hundreds of
included on the disk at the back of this
listings
of this code in Appendix C.
What You Will Need to Gse the Examples There For
are a
all
gram as the
few tools you
will
the examples in Part
that
need in order to use the examples
I,
you need nothing more than the Debug pro-
comes with DOS. In Part
Edit program in
DOS
in this book.
II
you will need
5 or later,
a simple text editor, such
and an assembler, such
as Microsoft's
Macro Assembler (MASM) or Borland's Turbo Assembler (TASM). All of the examples in this book have been tested on various versions of MASM and TASM. In Chapters 31 and 33, however, you will need MASM 6 (or later) or
TASM
to assemble the examples.
XIX
Assembly Language
Finally, to
QuickC
C
PC, Third Edition
for the
compile some of the
for
C
examples in Chapter 33, you will need
Windows, Borland C++,
or Microsoft
C 6.0 or later. All of these
compilers support in-line assembly and allow you to compile
Windows
programs.
Dskpatch In our
work with assembly language, we
displaying characters tion.
Dskpatch
these characters
is
a ftill-screen editor for disks
and numbers
for example, look at the sector
you could change learn
how
You will
DOS
get
file
XX
where
useful
and
it
in
hexadecimal nota-
will allow us to
By using Dskpatch you
change could,
DOS stores the directory for a disk and
names or other information. Doing on
so
is
a
good way
just
one program, though. Dskpatch
Many of these are general-purpose subroutines
when you write your own programs. Thus, not only is to the
to
a disk.
more out of Dskpatch than
book an introduction also a source
in a disk sector.
stores information
contains about 50 subroutines.
you will find
look directly at disk sectors and
will
and numbers stored there by DOS
80x86 and assembly-language programming,
of usefiil subroutines.
this it is
A
P
R
T
Machine Language
lA
P^ '8A
"
76
4C
ye
|c^
|3F
68
|96
i
\
|c1h|a|p|t|e|rj
\
Debug and Computer Learning
Arithmetic In
this
This
is
chapter you are going to learn
how the computer handles
a fundamental concept for assembly-language programs.
nificant impact
on
all
programs you
will write,
guage, or any other computer language.
arithmetic. It
has a sig-
whether in C, assembly lan-
Topics Covered A
Brief History of Intel Microprocessors
Counting the Computer
Way
Counting with Hexadecimal Numbers Using Debug
Doing Hex Arithmetic Bits, Bytes,
Two's Complement
Words, and Binary Notation
—An Odd Sort of Negative Number Summary
Assembly Language
In
this
for the
PC, Third Edition
chapter you will start working with the microprocessor inside your
puter right away.
You
computer arithmetic. of almost
will use a It is
a
to start
good
starting point because
Debug
called
assembly-language programs.
all
the chapters in this book,
all
Debug
program
com-
working with is
at the heart
We will continue to use Debug in
which will allow you to write and run very simple
programs.
A Brief History of Intel Microprocessors Before looking at assembly language, a few words are in order about microprocessors. Currently (as of in
PC compatible computers:
cessors (and Intel
Pentium). is
1
992) there are four main microprocessors used the 8088, 80286, 80386, and
working on the next generation, which
is
The 8088
microprocessor was
first
80486 microprowill
be called the
used in the original
IBM PC and
the slowest, least powerful microprocessor. Very few computers are built with
the
8088 microprocessor.
Next came the 80286 the
first
IBM AT, which was about four times faster,
in the
computer capable of running IBM's OS/2. The 80286
is
and
also the mini-
mum microprocessor required to run Windows 3.1. Most computers are currendy built around the
faster
additional capabilities that
80386 or 80486 microprocessors, which also have
Windows
can use.
The 80286, 80386, and 80486 are supersets of the 8088 means any programs written the others. to
8088 microprocessor
Almost all programs written
Windows,
DOS
for the
are written using just
computers. In
this
book we
microprocessor, which
for
8088
will
will
run on any of
MS-DOS or PC-DOS, as opposed
features so they will
run on
all
MS-
be covering mostly the 8088 instruc-
work on
MS-DOS
tions so the
programs you
However,
book you will find some coverage of Windows prothe protected mode of xhe 80286 and better microprocessors, which
gramming in is
will write will
used by operating systems such
many different microprocessors as
all
computers.
later in the
80x86 microprocessors.
as
Windows and OS/2. Because there are so we will refer to the entire family
used in PCs,
G
1
Learning Debug and Computer Arithmetic
Counting the Computer
Way
For your
how computers count.
foray into assembly language you will learn
first
That may sound simple enough. After
all,
you count
by starting
to II
at
one
and counting up:
1,2,3,4,5,6,7,8,9,10,
11.
A computer does not count that way. Instead, 11,
on
1
00, 101.
The numbers
ciated with our is
10, 11,
1
00,
numbering system with only two
a
more
it
counts to
and so on
digits,
are binary
and
1
0, instead
numbers, based of the ten asso-
familiar decimal numbers. Thus, the binary
number we know
equivalent to the decimal
1,10,
five like this:
number 10
as two.
We are interested in binary numbers because they are the form in which numbers are used ers thrive
by the 80x86 microprocessor inside your PC. But while comput-
on binary numbers, those
cumbersome
to write out.
The
strings
solution? Hexadecimal
compact way to write binary numbers. In to write
you
of ones and zeros can be long and
this chapter,
numbers: hexadecimal and binary. As you learn
will also learn
how
they store numbers
—
to the chapter
how
bits, bytes,
already know about binary and hexadecimal numbers,
you can skip
numbers
you will
—
a far
more
learn both
ways
computers count,
and words.
bits, bytes,
If
you
and words,
summary.
Counting with
Hexadecimal Numbers Since hexadecimal numbers are easier to handle than binary numbers least in
terms of length
will begin
—
at
with hexadecimal (hex for shon), and
DEBUG.COM, a program included with DOS. You will use Debug here
use
and
in later chapters to enter
tion at a time. Like
is
and run machine-language programs one
BASIC, Debug provides
instruc-
a nice, interactive environment.
know decimal numbers. To Debug, the number not ten. Since Debug only speaks in hexadecia hexadecimal number
But unlike BASIC, 10
—we
it
doesn't
—
mal, you will need to learn something about hex numbers. But a short side trip
and find out
a
little
about
Debug
itself.
first, let's
take
Assembly Language
for the
PC, Third Edition
Using Debug Why does this program carry the name Debug? Bugs, in the computer world, are mistakes in a program. A working program has no bugs, while a nonworking or "limping" program has at least one bug.
them by using Debug to run ing
how
a
You can find mistakes and correct
program one instruction
the program works. This
is
known
at a
time and by watch-
hence the name
as debugging,
Debug. According to computer of computing failed.
—
folklore, the
in particular, a
term debugging stems from the early days
day on which the Mark I computer at Harvard
After a long search, technicians found the source of their troubles: a small
moth caught between the contacts of a relay. The technicians removed the moth and wrote a note in the log book about "debugging" the Mark I.
1%
From
here on, in interactive sessions like this one, the text you type will
be in boldface against a gray background to distinguish computer's responses,
it
from your
as follows:
c>HTTTH
Type
the gray text
(DEBUG
in this example), press the Enter key,
and
you should see a response similar to the ones we show in these sessions. You won't always see exactly the same responses because your computer probably has a different amount of memory from the computer on which we wrote this book. (We will begin to encounter such differences in the next chapter.) In addition, notice that we use uppercase letters in all examples. This 1
(el)
Now, with
DOS
C>Qj|g||fi
only to avoid any confusion between the lowercase
and the number
lowercase
the
is
1
(one). If you prefer,
you can type
all
letter
examples in
letters.
those few conventions noted, start
prompt (which
is
C>
Debug by typing its name
in the following example).
after
n
1
The hyphen you bol, just as
To
leave
C>
is
see in response to a
DOS
Debug and
prompt and
prompt.
command
means Debug
DOS,
return to
press Enter.
your
It
Learning Debug and Computer Arithmetic
if
Debug's prompt sym-
waiting for a
Q (for
just type
Try quitting now,
is
is
you
command.
Quit) at the
hyphen
and then return
like,
to
Debug.
C>DEBUG
Now we can get down
to learning about hex
numbers.
Doing Hex Arithmetic We will use a Debug command called H. H its
by
name suggests,
it
starting with 2 + 3.
H works
We know
that 2 + 3 = 5 for decimal numbers.
numbers? Make sure you
true for hex
short for Hexarithmetic, and as
is
adds and subtracts two hex numbers. Lxt's see how
prompt, type the following screened
are
still
in
Debug
Is this
and, at the hyphen
text:
-H 3 2
0005
0001
Debug prints both the sum (0005) and the difference (0001) of 3 and 2. The Hexarithmetic command, shown in Figure 1-1, always calculates the sum and difference of
two numbers,
hex and decimal numbers: 5 ence (3
—
2).
as
it
did here. So
the
is
sum of 3
far,
the results are the
+ 2 in decimal, and
Sometimes, however, you can encounter a few
1 is
same
for
the differ-
surprises.
For example, what if you typed
H 2 3, to add and subtract two and three, instead
of three and two? If you try
you
as
it
may look,
however,
it
FFFF
is
a
get
FFFF, instead of-1,
number. In
fact,
it is
for
2-3.
Strange
hex for -1.
-H 2 3
0005
FFFF
We will come back to this rather unusual -1 realm of slightly larger numbers to see
shortly.
how an F
But first,
let's
explore the
can appear in a number.
Assembly Language
for the
PC, Third Edition
Number A
Number B
-H 3D5C 2A10 676C 134C
A+B
A-B
Figure 1-1: The Hexarithmetic command.
To
see
what the Hexarithmetic command does with larger numbers, which would give you the decimal number 10.
try nine
plus one, -H 9
1
000A
0008
Nine plus one if
we
try for
equals A? That's right:
A
is
an even larger number, such
the hex
number for
ten.
Now, what
as 15?
H 9 6
000F
0003
If you try other
—
gether
numbers between ten and fAeen, you will find 16
through F (0 through 9 and A through
hexadecimal comes from hexarepresent 16.
The
digits
(6),
F), see
Figure 1-2.
plus deca- (10), which,
digits alto-
The name
when combined,
through 9 are the same in both hexadecimal and
decimal; the hexadecimal digits
A
through F are equal to the decimals 10
through 15.
Why does Debug speak in hexadecimal?
Soon you will
see that
you can write
As you may already suspect, 256 known as a byte, and the byte plays a major role in computers and in this book. You will find out more about bytes near the end of this chapter, but for now we will continue to concentrate on learning hex, the only number system known to Debug and hex math.
256
different
also bears
8
numbers with two hex
some
digits.
relationship to the unit
1
Decimal
Hex
n
Learning Debug and Computer Arithmetic
digit
1
1
2 3 4 5 6 7 8
2 3
These
4
same
5 6 7 8 9
and hex.
9 10
are the both decimal
digits
for
A B C D
11
12 13 14 15
These
digits
hexadecimal
new
are
digits.
E F
Figure 1-2: Hexadecimal digits.
Converting Hexadecimal to Decimal Thus
far,
you have learned
single-digit
hex numbers.
numbers and how you convert
represent larger hex
Now,
these
let's
see
numbers
how you
to decimal
numbers. Just as with decimal numbers,
you can build multiple-digit hex numbers by
adding more
Suppose, for example, you add the number
digits
on the
left.
to the largest single-digit decimal ber,
10
(ten).
— 10
in
hex
is
h
after
16 and 10
is
1
result
is
a two-digit
1
num-
to the largest single-digit
hex
again.
really 16,
not 10. This could become rather conftising.
We need some way to tell these two letter
The
9.
What happens when you add
number, T? You get 10 But wait
number,
1
Os apart
any hex number. Thus, you can
.
From now on we will place tell
that
lOh
is
the
hexadecimal for
decimal ten.
Now let's look at how to convert numbers between hex and decimal. You know that
lOh
is
16,
but
how do you
convert a larger hex number, such as
converted to a decimal number without counting up to
how is
the decimal
number 1 73 convened
to hex?
D3h from
D3h,
lOh? Or,
Assembly Language
for the
PC, Third Edition
You cannot
rely
on Debug
Chapter 10,
we
will write a
for help, because
program
it
cannot speak
in decimal. In
hex number into decimal
to convert a
notation so that our programs can talk to us in decimal. But right now,
have to do these conversions by hand.
will
familiar
we
We will begin by returning to the
world of decimal numbers.
What does the number 276 mean? you have two hundreds, seven
In grade school, you learned that
tens,
and
six ones.
276 means
Or, more graphically
as fol-
lows:
2
7 6
*
100 =
200
*
10 =
70
*
=
6
=
276
1
276
Well, that certainly helps illustrate the meanings of those the
same graphic method with a hex number?
Consider the number
and there
are 16
hex
D3h
mentioned
digits, versus
earlier.
D
-^ 13
*
16 =
3^3*1=
D3h
=
is
the hexadecimal digit 13,
D3h
is
thirteen sixteens
3
211
by 1000, 100,
digits
10,
and
by 16 and 1.
Which
digits 1.
by 100,
You would
10,
10
as follows:
10'
=
1000
10'
=
100
10'
=
10
10"
=
1
and
1;
for the
multiply four deci-
four numbers would you use with
four hex digits? For decimal, the numbers 1000, 100, 10, and
of 10,
use
as follows:
For the decimal number 276, you multiply
digits
Can we
208
hex number D3, multiply
mal
D
10 for decimal, so
and three ones. Or, presented graphically
digits.
Of course.
1
are
all
powers
You can
use the
same exact method
numbers
stead of 10, so the four 16'
=
4096
16'
=
256
16'
=
16
16"
=
bers. (See Figure 1-3 for
^
A C
G
for
hex
Debug and Computer Arithmetic
Learning
digits,
but with powers of 16,
in-
are as follows:
1
For example, you can convert
3
1
3
-^10 -^12
* *
*
8-^8*
3AC8h
by using these four num-
more examples.)
4096 = 12288 256
=
2560
16
=
192
1
=
8
=
15048
3AC8h
-»
7
^
C
7
*
12
*
7Ch
F 9
^ F
3
* *
9
C
10 15
*
12
*
*
AFlCh
B
-* -»
8
D
1
^
768
=
9
1,017
4,096 256 16 1
= = = =
40,960 3,840 16 12
44,828
3
*
11
*
8
*
65,536 4,096 256
13
*
16
2^2*
3B8D2h
=
16 = 240
=
^
3
256
=
1^1* ^ -*
124
15
3F9h
A
16 = 112 1 = 12
=
-^ -^ -*
3
Figure 1-3:
to decimal
1
= = = = =
=
196,608 45,056 2,048 208 2
243,922
More hexadecimal to decimal conversions.
11
Assembly Language
for the
PC, Third Edition
Now let's discover what happens when we add hex numbers than one
digit.
For
this,
we will
use
that have
more
Debug and the numbers 3A7h and lEDh,
as follows: •H 3A7 1ED
0594
01BA
So you see that 3A7h + these
lEDh =
594h.
You can check the results by converting
numbers to decimal and doing the addition (and subtraction,
in decimal form; if you are
more adventurous, do the
if you
wish)
calculations directly in
hex.
Five-Digit So
far,
hex math
Hex Numbers is
quite straightforward.
What happens when you try adding
even larger hex numbers? Try a five-digit hex number, 1-4 for
as follows (See
Figure
more examples):
-H 5C3Fe 4BC6 "
Error
11
+
1
F451 + CB03 1BF54
3A7
92A CDl
C +
19
11
1111
BCD8 + FAE9 1B7C1
Figure 1-4:
That here?
is
12
BCD8 0509 ClEl
Why does Debug say that you have an error
reason has to do with a unit of storage called the word. Debug's
Hexarithmetic
enough
+
More examples of hexadecimal addition.
an unexpected response.
The
D
command works only with words, and words happen to be long
to hold four
hex
digits,
no more.
O
1
You
will learn
more about words
you can work only with four hex
few pages, but for now, remember that
Thus,
digits.
if you try to
add two four-digit
COOOh and DOOOh (which should give you 19000h), 9000h instead. Debug keeps only the four rightmost digits of the
hex numbers, such
you get
in a
Debug and Computer Arithmetic
Learning
as
answer. -H ceee oeee
F000
9000
Converting Decimal to you have only seen
So
far
at
how
Hex
the conversion
to convert decimal
numbers
from hex
to hex.
earlier, in
10 you will create a program to write the 80x86's numbers bers; in
Chapter 23, you
will write
Now let's look
to decimal.
As mentioned
Chapter
decimal
as
num-
another program to read decimal numbers
you
into the 80x86. But, as with decimal-to-hex conversions,
doing the conversions by hand. Again,
by
start
recalling a bit
will begin
by
of grade school
math.
When you
first
mainder of
1
.
learned division,
you would divide 9 by 2
to get
We will use the remainder to convert decimal
See what happens
when you
4 with a
numbers
re-
to hex.
repeatedly divide a decimal number, in this case
493, by 10? 493
10
/
49
/
49 remainder 3
=
4
=
1
4/10
=
remainder
9
remainder
4
4 9 3
The
digits
of 493 appear
with the rightmost digit
as the
(3).
remainder in reverse order
You saw in the last section
a hex-to-decimal conversion
was
to replace
that
—
that
all
you needed
is,
starting
for
powers of 10 with powers of 16.
For a decimal-to-hex conversion, can you divide by 16 instead of 10? Indeed, that
is
the conversion method. For example, find the hex
can divide by
1
6,
number for 493. You
you get the following:
13
Assembly Language
for the
PC, Third Edition
493
/
16 = 30 remainder 13 (Dh)
30
/
16 =
1/16
1
=
remainder 14 (Eh)
remainder
1
(1 h)
4 9 3
lEDh 16,
to
is
E D
h
the hex equivalent of decimal 493. In other words, keep dividing by
and form the
it.
1
final
Figure 1-5 gives
hex number from the remainders. That's
more examples of decimal
to
/
16 = 66
Remainder
13
66
/
16 =
Remainder
2
4
/
16 =
Remainder
4
1069
all
there
hex conversions.
f 4
T t t 2 D h
1069
4
57,109
/
16 = 3,569
Remainder
5
i 3,569
/
16 =
223
Remainder
1
Remainder
15
Remainder
13
'
; 223
/
16 =
/
16
13
^ 13
57,109 Figure 1-5:
14
More examples of hexadecimal conversions.
t t T t D F 1 5 h
is
n
1
Learning Debug and Connputer Arithmetic
Working with Negative Numbers If
you
recall,
there
FFFFh
said that
How can
65535.
if
5-1 =
4. Is that
an unanswered puzzle in the number FFFFh.
actually -1. Yet, if you convert
that be?
you add FFFFh
Well,
and you
is
is still
Does
it
(alias
behave
-1) to
FFFFh
as a negative
to decimal,
we
We get
number?
the result should be 4, because
5,
what happens? Use Debug's
H command to add 5 and FFFFh,
see the following:
-H 5 FFFF
0006
0004
Debug
seems to treat
programs we
When one
FFFFh
will write.
To
But FFFFh won't always behave
as -1.
see
why
not,
let's
adding two decimal numbers, you
to the next
column,
do
this
as
-1 in
addition by hand.
will often find yourself carrying a
as follows:
9 5
1
The
5
8
5
3
addition of two hex numbers
isn't
with a carry into the next column,
much different. Adding 3
to
F
gives 2,
as follows:
F h 3 h 1
2 h
Now, watch what happens when you add
5 to
FFFFh.
15
Assembly Language
PC, Third Edition
for the
1111 h
5
F F F F h
+
4 h
1
Since
Fh
+ Ih = lOh, the successive carries neatly
position. If you ignore this
Strange as
seems,
it
1
FFFFh
,
you have the
behaves
as
called an overflow because the number
only the
last
a
correct answer for 5
-1 when you ignore
is
into the far left
1
-
namely,
4.
this overflow. It
is
1
:
now five digits long, but Debug keeps
(rightmost) four digits.
overflow an error, or
Is this
move
is
the answer correct? Well, yes
and
yes.
You can
choose either answer. Don't the answers contradict each other? Not
really,
because you can view these numbers in either of two ways.
Suppose you take FFFFh
as
happens to be the
number you can
case
FFFFh
four-digit
answer
is
is
largest
called an
equal to 65536. This
wwz^^^^ number.
numbers are positive. Adding 5
correct. In the case
is
a positive
number, and
it
write with four hex digits. In this It is
to
unsigned because you said
all
FFFFh gives you 10004h; no other
of unsigned numbers, then, an overflow
is
an
error.
On the other hand, you can treat FFFFh as a negative number, as Debug did when you used —1
as
long
as
the
to
add FFFFh
you ignore the overflow. In
FFFFh
all
flow
not an error.
is
H command
behave
as negative
numbers. For
fact,
the
to 5.
FFFFh behaves
as
numbers 8000h through
5/^«f
Topics Covered Rotating
Numbers through
the Carry Flag
Adding the Carry Flag to a Number Looping
—Repeating a Block of Code
Building a Program to Display a Binary
Stepping over INTs with the Proceed
Summary
Number
Command
Assembly Language
In
PC, Third Edition
for the
chapter you will build a program to write binary numbers to the screen
this
of zeros and ones.
as strings
You have most of the knowledge you
need, and
your work here will help solidify ideas you have already covered. This chapter adds a few instructions to those you already know, including another ver-
also
sion of
ADD and some instructions to help repeat parts of your program. Let's
begin by learning something completely new.
Rotating Numbers through the Carry Flag when you first encountered hex arithmetic, you found that addFFFFh should give you lOOOOh, but does not. Only the four hex digits to the right fit into one word; the 1 does not fit. You also found that this 1 is an overflow and that it is not lost. Where does it go? It is put into something called a flag ^in this case, the Carry Flag, or CF. Flags contain one-bit numIn Chapter 2, ing
1
to
—
bers, so fifth
Go
they can hold either a zero or a one. If you need to carry a one into the
hex
digit,
it
back to the
AX and
into
1
of the second
goes into the carry
ADD
into
line
flag.
instruction of Chapter 3
BX, then
of Debug's
trace
through the
because your
AX,BX). Put FFFFh
R display, you will see eight pairs of letters. The
NC or CY, the carry flag. Right now, ADD instruction resulted in an overflow of you will see that
of these, which can read either
last
(ADD
ADD instruction. At the end is
1
the carry status reads
CX {Carry). The carry bit now is
,
(or, as
1
we will
say,
it's
set).
To
confirm that you have stored a seventeenth
bit for a byte addition),
tracing through the
add one
to the zero in
bit here
(it
would be the ninth
AX by resetting IP to
ADD instruction again. The carry flag
is
lOOh and
affected
by each
ADD instruction, and this time there shouldn't be any overflow, so the carry should be
reset.
stands for
No
You
The
carry does
Carry, in the
become
learn about other status flags later in this book. If
can find information about them right
your
56
zero, as indicated
DOS manual.
by the
NC, which
R display. you
are curious,
you
now under Debug's R command
in
n
4
Let's review the task
mation could be
want
of printing a binary number to see
You
useful.
to pick off the bits
example, the
first
If you
would want to
move
could
print in the
this entire
the one into the carry flag and adding a
byte
left
Numbers
the carry infor-
at a time, so
you
left to right.
For
of your number, one by one, from
character you
would be the one.
how
only one character
will print
Printing Binary
number 1 000 0000b one
place,
dropping
to the right side, then repeat the
process for each succeeding digit, the carry flag would pick ofi^your binary digits.
You can do just this with a new instruction called RCL see
how
it
functions, enter the short
3985:0100 D0D3
RCL
This instruction
The
flag.
BL
rightmost bit position
other bits are
moved
you
you
Figure
bit
(hence the
RCL
,1)
moves
bit currently in the carry
4-L
In the process,
enough
After
left.
moved back into number. Place B7h in
this rotate instruction several times.
all
rotations (17 for a
their original positions
the
BX
the
register,
and
then trace
Converting your results to binary,
will see the following: BL register
Carry
110
111
B7h
110 110
1110
6Eh
10 11
10 10
BAh
10 11
111
B7h
10 1
1
1
In the
first
moves
flag
into bit
number
You
110
rotation, bit
moves continue nal
moving the
bits are
get back the original
through
by one
called rotate, because
is
(0) as in
or rotated to the
word, 9 for a byte) the
as follows:
to the left
instruction
the leftmost bit into the carry flag, while flag into the
To
BL,1
rotates the byte in
through the carry
program
{Rotate Carry Left).
is
DDh
1
of BL;
all
other bits
rotating the bits to the
back in the
you
After
still
9
rotations
7 of BL moves into the carry
BL
move
left
flag;
the bit in the carry
one position. Succeeding
left until, after
nine rotations, the origi-
register.
are getting closer to building a
screen, but
We start here
need a few
program
to write binary
other pieces. Let's see
bit in the carry flag into the character
or
numbers
how you can
to the
convert the
1
57
Assembly Language
for the
PC, Third Edition
CF
BL
0110 1110
RCL
Figure 4-1: The
BL,1
instruction.
Adding the Carry Flag to a
Number
The normal
ADD
instruction, for example,
numbers. Another instruction,
ADD AX,BX,
ADC (Add with
the two, as before, plus one bit from the carry
Carry), adds three
flag. If you
will discover that
30h
is
So, adding the carry flag to
30h
gives the character
table,
and
1
you
when the carry is set. Thus,
the character
if
DL =
simply adds rwo
and 31h
is
when
the character
the carry
and the carry flag is set
ing the following instruction adds DL(0) and Ih (the carry) to
30h
is
1.
clear,
(1), execut('0'),
which
31h (T).
gives
ADC
numbers:
look in your ASCII
DL,30
With one
instruction
you have converted the carry
to a character that
you can
print.
At this point,
rather than run through an example of ADC, wait until
you have
a complete program. After you have built the program you will execute
structions
one
at
a time in a procedure called single-stepping.
cedure you will see both
58
you need one more
RCL, ADC, and INT 21h
for each bit in a byte.
in-
this pro-
how the ADC instruction works and how it fits nicely
into your program. First,
repeat your
Through
its
instruction
which you will use
(print) instructions eight times
to
—once
G
4
Printing Binary
Numbers
—
Looping Repeating a Block of Code As mentioned, the
RCL instruction is not limited to rotating bytes;
rotate entire words.
LOOP
tion. eral.
is
We will use this ability to demonstrate the ZOO/* instruc-
As with BASIC'S
ex. Each time
ister
FOR-NEXT command in Basic, but not as genFOR-NEXT loop, you need to tell LOOP how many
it
You do
this
by placing your repeat count
in reg-
goes through the loop, the 80x86 subtracts one from
CX becomes zero, LOOP ends the loop.
Why the CX register? The C in CX stands for as a
can also
similar to the
times to run through a loop.
CX; when
it
Count.
You can
use this register
general-purpose register, but as you will see in the next chapter, you can
CX register with other instructions when you wish
also use the
to repeat op-
erations.
Here
BL
is
a simple
into
BH
program that
rotates the
(but not the reverse, because
396F 0100 BBC5A3
MOV
BX,A3C5
396F 0103 B90800
MOV
CX,0008
396F 0106 D1D3
RCL
BX,1
396F 0108 E2FC
LOOP
0106
396F 01 0A CD20
INT
20
BX register left eight times, you
moving
rotate through the carry flag):
The loop starts at 1 06h (RCL BX, 1 and ends with the LOOP instruction. The number following LOOP ( 1 06h) is the address of the RCL instruction. When you run the program, LOOP subtracts one from CX, then jumps to address 106h if CX is not equal to zero. The instruction RCL BX,1 (Rotate )
Carry
Left,
one place)
is
executed eight times here, because
CX
is
set to eight
before the loop.
You may have noticed that, instruction
ment
in
is
at the
unlike the
FOR-NEXT loop in BASIC, the LOOP
end of our loop (where you would put the
BASIC). The
start
of the loop, the
FOR has in BASIC. cal, you can see that the LOOP instruction
RCL
special instruction like
instruction at 106h, has
If you
is
NEXT state-
know
no
a language like Pas-
somewhat akin
to the
REPEAT-
UNTIL pair of instructions, where the REPEAT instruction just labels the start of the block of instructions to loop through.
59
Assembly Language
for the
PC, Third Edition
0106:
Decrement
CX
LOOP 0106 Continue
when CX 20
INT Figure 4-2: The
There
=
LOOP instruction.
are different
ways you could execute your small program.
If you
type G, you won't see any change in the register display, because all
the registers before
ters
an
isters.
and
INT
starts carrying
it
20 instruction
Try G. You
(as it will in
will see that
one step
at a time,
Debug saves
G command. Then, if
your program),
it
restores
it
encoun-
all
the reg-
IP has been reset to lOOh (where you started),
any
that the other registers don't look
If you have the patience, it
out a
you can
trace
different, either.
through
you can watch the
this
registers
program, instead. Taking
change
at
each step, as
lows:
-t AX=0000
BX=0000
CX=0000
DX=0000
SP=FFEE
DS=0CDE
ES=0CDE
SS=0CDE
CS=0CDE
IP=0100
0CDE:0100 BBC5A3
MOV
BX=A3C5
CX=0000
DX=0000
SP=FFEE
DS=0CDE
ES=0CDE
SS=0CDE
CS=0CDE
IP=0103
MOV
BP=0000
SI=0000
DI=0000
NV UP DI PL NZ NA PO NC
BX,A3C5
AX=0000
0CDE:0103 B90800
BP=0000
SI=0000
DI=0000
NV UP DI PL NZ NA PO NO
CX,0008
-T
AX=0000
BX=A3C5
CX=0008
DX=0000
SP=FFEE
DS=0CDE
ES=0CDE
SS=0CDE
GS=0CDE
IP=0106
0CDE:0106 D1D3
60
RCL
simply
BX,1
BP=0000
SI=0000
DI=0000
NV UP DI PL NZ NA PO NC
fol-
4
AX=0000
BX=478A
CX=0008
DX=0000
SP=FFEE
DS=0CDE
ES=0CDE
SS=0CDE
CS=0CDE
IP=0108
0CDE:0108 E2FC
LOOP
BP=0000
n
Printing Binary
Numbers
DI=0000
SI=0000
OV UP 01 PL NZ NA PO CY
0106
-T
AX=0000
BX=478A
CX=0007
DX=0000
SP=FFEE
DS=0CDE
ES=0CDE
SS=0COE
CS=0CDE
IP=0106
0CDE:0106 D1D3
RCL
BP=0000
01=0000
SI=0000
OV UP 01 PL NZ NA PO CY
BX.I
-f AX=0000
BX=C551
CX=0001
DX=0000
SP=FFEE
OS=0COE
ES=0COE
SS=0CDE
CS=0COE
IP=0108
0CDE:0108 E2FC
LOOP
BP=0000
01=0000
SI=0000
NV UP 01 PL NZ NA PO CY
0106
-T
AX=0000
BX=C551
CX=0000
OX=0000
SP=FFEE
OS=0COE
ES=0COE
SS=0CDE
CS=0CDE
IP=010A
0CDE:010A CO20 Alternatively,
cluding, the sult If
INT
you can type
INT 20
BP=0000
01=0000
SI=0000
NV UP 01 PL NZ NA PO CY
20
G
lOA
to execute the
instruction at lOAh.
The
program up
to,
but not in-
then show the
registers will
re-
of your program.
you
try this,
you
will see
CX
=
depending on the value of the carry your program's register,
Later,
but
either
BX
=
C551
see other
a Binary
BX
=
C5D1,
because you rotated
is
now
in the
number
BH
BX through the carry.
ways of rotating without going through the carry.
get back to the goal of printing a
Building a
or
you ran the program. The C5
MOV instruction put into BL at the start
BL doesn't contain A3,
you will
and
flag before
Let's
in binary notation.
Program to Display
Number
You have seen how to strip off binary digits one at a time and convert them to ASCII characters. If you add an INT 2 1 h instruction to print your digits, your program will be finished as you can see in the following program. The first
61
Assembly Language
for the PC, Third Edition
instruction sets
AH to 02 for the INT 21h function call (recall, 02 tells DOS
to print the character in the
DL register).
3985 0100 B402
MOV
AH, 02
3985 0102 B90800
MOV
CX,0008
3985 0105 B200
MOV
DL,00
3985 0107 D0D3
RCL
BL,1
3985 0109 80D230
ADC
DL,30
3985 010C CD21
INT
21
3985 010E E2F5
LOOP
0105
3985 0110 CD20
INT
20
The program
is
as follows:
You have seen how all the pieces work alone; here is how they work together. You rotate BL (with the instruction RCL BL,1) to pick off the bits of a number. Pick a number you want printed in binary and load it into the BL register; then run this program with a G command. After the INT 20h instruction, the still
G command
contains the
restores the registers to the values they
number you
had
before.
BL
see printed in binary.
The ADC DL,30 instruction in your program converts the carry flag to a or a 1 character. The instruction MOV DL,0 sets DL to zero first, then the ADC instruction adds 30h to DL, and then finally adds the carry. Since 30h is the ASCII code for a 0, the result of ADC DL,30 is the code for when the carry is clear (NC) or 1 if the carry is set (CY). to see what happens when you run this program, trace through it. mind that you will need to be a bit careful in single-stepping through it with the T command. It contains an INT 21h instruction and, as you saw when you first encountered INT 21h, DOS does a great deal of work for that one instruction. That is why you cannot use T on the INT 21. If you
Keep
want
in
You can, however, the final
INT
tracing, type
struction.
trace
through
all
the other instructions in this program except
20, which won't concern
G
Your
you
until the ver\' end.
lOE each time you loop through and reach
G command,
followed by an address, will
the
tell
Debug
tinue running the program until IP becomes the address (lOE)
That
Debug
is.
through
it,
will execute the
INT
62
to con-
entered.
LOOP
instruction at lOE so you number you type after G is very useful when you are trying to
but stops before executing the
as a breakpoint;
you
in-
21 h instruction without your tracing
can return to tracing through the program. (The
known
During your
INT 21h
breakpoints are
4
G
Printing Binary
Nunnbers
understand the inner workings of programs.) Finally, terminate the program
when you
INT 20h
reach the
instruction by typing the
G command by itself.
Stepping over INTs with the Proceed Command Whether
or not you have tried out the instructions to trace through the pro-
gram, you have seen that an instruction
INT instruction an
to trace over
that starts
INT
at, say,
instruction,
tion immediately following the
As
it
like
G
lOE allows you
to trace
ovemn
lOCh. But that means each time you want
you need
INT
to find the address
of the instruc-
instruction.
is a Debug command that makes tracing through INT much simpler. The P (Proceed) command does all the work for To see how it works, trace through the program, but when you reach the
turns out, there
instructions
you.
INT 21h
instruction type P, rather than
G
lOE.
We will make heavy use of the P command in the rest of this book, because is
a nice
way
to trace over
commands DOS.
such
as the routines inside
That
is all
we will
this
is
program
The ASCII code
INT, which
call
on
large
programs
cover about printing binary numbers as strings of zeros and
ones for now. Here
modify
like
it
for
b
a simple exercise for to print a ^ at the is
you
to practice
on
—
see if you can
end of your binary number. (Hint:
62h.)
Summary This chapter provided a chance to catch your breath a
on new concepts
in Chapters
1
through
3.
bit after
your hard work
So where have you been, and what
have you seen?
You had your was of
first
encounter with
special interest because
it
flags
made
and had
a look at the carry flag. This
the job of printing a binary
number
63
Assembly Language
for the PC, Third Edition
quite simple.
which
It
did so as soon as you learned about the rotate instruction
rotates a byte or
word
to the
left,
one
RCL,
bit at a time.
Once you learned about the carry flag and rotating bytes and words, you learned a new version of the add instruction, ADC. You used this later to build your program to print a number in binary notation. This
is
register
where the
structions a
That
LOOP
instruction entered the scene.
By
loading the
CX
with a loop count, you could keep the 80x86 executing a loop of in-
is all
number of times. You
you needed
to write
set
CX to 8,
to execute a loop eight times.
your program. You
the following chapters. In the next chapter
will use these tools again in
we will print a binary number By the time we finish Chapter
in
as Debug does. 5, you will have a better idea of how Debug translates numbers from binary to reading the numbers hex. Then, we will move on to the other end of Debug
hexadecimal notation, just
—
typed in hex and converting them to the 80x86's binary notation.
64
C
H A
I
I
Printing in In
I
P
I
T
I
F
I
Numbers
Hex
this chapter
you
displays a binary
will learn
number
some new
tools
needed to build a program that
You will learn about the how to use the CMP (com-
in hexadecimal notation.
zero flag, as well as several other
flags.
You will
learn
and the JZ (jump if zero) conditional jump instruction to control your program. Finally, you will learn about Boolean logic
pare) instruction to set these flags,
and the AND
instruction.
R
Topics Covered Comparing Numbers Printing a Single
Hex
Summary
^^
Digit
— Assembly Language
for the
PC, Third Edition
fairly straightforward. You were lucky bemade it easy to print a binary number as a string of and 1 characters. Now we will move on to printing numbers in hex notation. The work will be a bit less direct and we will begin to repeat ourselves in our pro-
1 he program
in
Chapter 4 was
cause the carry flag
grams, writing the same sequence of instructions more than once. But that type
of repetition won't
In Chapter 7
last forever.
you
will learn
about procedures
more than one copy of a group some more useful instructions and see how to
or subroutines that eliminate the need to write
of instructions. print
numbers
First,
you
learn
in hex.
Comparing Numbers In the
last
carry flag,
chapter you learned something about status flags and examined the
which
is
represented as either
CY or NC in Debug's R display. The
other flags are equally useful, keeping track of the status for the operation. There are eight flags altogether,
and you
will learn
arithmetic
last
about them
as
they are needed.
Other Status Flags Recall that flag
is
CY means
In
0.
all flags 1
the carry flag
means
true
instruction results in 0, the flag
—and you would
true flag
would be
Look
at
reset to
see
to subtract
two numbers. flag will
known
in the
tests
,
or
If the
whereas
NC means the carry would be
as the Zero Flag
if
a
set to
SUB 1
Otherwise, the zero
Zero).
the zero flag.
appear as
set,
means false. For example,
R display as ZR (Zero).
—NZ {Not
an example that
and the zero
it
is 1
and
You
two numbers
will use the
SUB
instruction
are equal, the result will be zero,
ZR on your display.
Enter the following sub-
tract instruction:
396F:0100 29D8
Now,
trace
SUB
AX,BX
through the instruction with a few different numbers, watching
ZR or NZ to appear in the zero flag. If you place the same number (F5li in the following example) into both the AX and BX registers, you will see the for
zero flag set after one subtract instruction, lows:
68
and cleared
after another, as fol-
5
Printing
r\
Nunnbers
in
Hex
-R
AX=00F5
BX=00F5
CX=0000
DX=0000
SP=FFEE
DS=0CDE
ES=0CDE
SS=0CDE
CS=0CDE
IP=0100
0CDE:0100 29D8
SUB
BP=0000
SI=0000
DI=0000
NV UP DI PL NZ NA PO NC
AX, BX
-T
AX=0000
BX=00F5
CX=0000
DX=0000
SP=FFEE
DS=0CDE
ES=0CDE
SS=0CDE
CS=0CDE
IP=0102
0CDE:0102 3F
BP=0000
SI=0000
DI=0000
NV UP DI PL ZR NA PE NC
AAS
-R IP
IP 0102
:1M -R
AX=0000
BX=00F5
CX=0000
DX=0000
SP=FFEE
DS=0CDE
ES=0CDE
SS=0CDE
CS=0CDE
IP=0100
0CDE:0100 29D8
SUB
BP=0000
SI=0000
DI=0000
NV UP DI PL ZR NA PE NC
AX, BX
-T
AX=FF0B
BX=00F5
CX=0000
DX=0000
SP=FFEE
DS=0CDE
ES=0CDE
SS=0CDE
CS=0CDE
IP=0102
0CDE:0102 3F If
SI=0000
DI=0000
NV UP DI NG NZ AC PO CY
AAS
you subtract one from
zero, the result
complement form. Can you tive or negative?
(Negative)
BP=0000
Yes
and PL
tell
—another
(Plus),
and
set to
1
FFFFh, which
is
-1
in two's-
R display whether a number is posi-
from the
flag, called is
is
the Sign Flag, changes between
when
a
number
is
NG
a negative two's-
complement number. Another new flag you will be interested in
is
the Overflow Flag, which changes
OV (Overflow) when the flag is 1 and NV (No Overflow) when the The overflow flag is set if the sign bit changes when it shouldn't. For example, if you add two positive numbers, such as 7000h and 6000h, you get a negative number, DOOOh, or -12288. This is an error because the result overflows the word. The result should be positive, but isn't, so the 80x86 sets the between flag
is
0.
overflow
flag.
(Remember,
would not be an Try several trying
error
different
them out
if
and you would ignore the overflow
numbers
until
you were dealing with unsigned numbers,
you
to see if you can set
and
reset
are comfortable with them.
this
flag.)
each of these
flags,
For the overflow, sub-
—
tract a large negative number from a large positive number for example, 7000h - 8000h, since 8000h is a negative number equal to -32768 in two'scomplement form.
69
Assembly Language
for the
PC, Third Edition
Using the Status Bits
—Conditional Jumps
Now you are ready to look at a set of instructions
called the conditionaljump They allow you to check status flags more conveniently than you have been able to so far. The instruction JZ [Jump if Zero) jumps to a new
instructions.
address if the
arithmetic result was zero. Thus, if you follow a
last
struction with, say,
80x86
the
than
to
at the
The JZ
jump
JZ to
1
SUB
in-
5A, a result of zero for the subtraction would cause
and
start
executing statements at address 15Ah, rather
next instruction.
instruction tests the zero flag, and, if it
is
set
The
(ZR), does a jump.
is JNZ {Jump ifNot Zero). Let's look at a simple example that JNZ and subtracts one from a number until the result is zero, as follows:
opposite of JZ uses
396F:0100 2C01
SUB
AL,01
396F:0102 75FC
JNZ
0100
396F:0104 CD20
INT
20
Put a number
like three in
AL
so
you
will
go through the loop a few times,
then trace through this program, one instruction tional branches work.
at a time, to see
how condi-
We put the INT 20h instruction at the end so typing G
by accident won't drop off the end of your program;
it's
a
good defensive
prac-
tice.
Using
CMP to Compare Numbers
You may have
noticed that using
tentially undesirable side effect
allows
you
to
out changing the
first
what happens,
through -A lee
0CDE:0100 CMP AX,BX -T
70
compare two numbers has the po-
of changing the
number. The
many set
result
conditional
both
is
jump
AX and BX to
this instruction, as follows:
0CDE:0102
to
first
do the subtraction without storing the
can use one of the see
SUB
number.
CMP {Compare)
result an^'where
used only to
and with-
set the flags, so
instructions after a compare.
the
same number, F5h, and
you
To
trace
G
5
AX=00F5
BX=00F5
CX=0000
DX=0000
SP=FFEE
DS=0CDE
ES=0CDE
SS=0CDE
CS=0CDE
IP=0102
0CDE:0102 3F
The
To
zero flag
use
now
is
set
in
Hex
01=0000
NV UP DI PL ZR NA PE NC
(ZR), but F5h remains in both
registers.
CMP to print a single hex digit. Create a set of instructions that uses
manner similar
flow of your program, as
to
BASIC's
will use the flags to test for
is
SI=0000
Mumbers
AAS
flags to alter the
on.
BP=0000
Printing
IF-THEN
LOOP did
statement. This
such conditions
in the last chapter, in a
new set of instructions
as less than, greater than,
and so
You will not have to worry about which flags are set when the first number than the second; the instructions know which flags to look at.
less
Printing a Single Start
Hex Digit
by putting a small number (between
any number between
and Fh
is
your choice to
ASCII
character
a single
and Fh) into the
BL register.
Since
equivalent to one hex digit, you can convert
and then print
it.
Look
at the steps
needed to do the conversion.
Character
ASCII Code
Character
(Hex) /
2F 30
1
31
2 3 4 5 6 7 8 9
32 33 34 35 36 37 38 39
:
>
3A 3B
ASCII Code (Hex)
< = > 9
@
3C 3D 3E 3F 40
A
41
B
42 43 44 45 46 47 49
C D E F
G H
Figure 5-1: Partial ASCII table showing the characters used by hex
The ASCII characters
A
through
F,
digits.
through 9 have the values 30h through 39h; the characters
however, have the values 4lh through 46h
(see Figure 5-1).
71
Assembly Language
for the
The problem characters.
is
PC, Third Edition
that these
two groups of ASCII
by seven
As a result, the conversion to ASCII will be different for the two groups
of numbers (0 through 9 and
Ah
through Fh), so you handle each group
differ-
A BASIC program to do this two-part conversion looks like this:
endy. IF
characters are separated
BL < &H0A THEN BL = BL + &H30
ELSE BL = BL + &H37
END IF
The BASIC conversion program
is
fairly simple.
Unfortunately, the 80x86's
machine language doesn't include an ELSE statement.
It is far
more primitive
BASIC is, so you will need to be somewhat clever. Here BASIC program, this time one that mimics the method you will
than
is
another
use for the
machine-language program. BL = BL + &H30 IF
BL >= &H3A THEN BL = BL + &H7
END IF
You can convince yourself that this program works by trying it with some choice examples. The numbers 0, 9, Ah, and Fh are particularly good because these four numbers cover all the boundary conditions, which are areas where we often run into problems. Notice that
we just
Here,
wrote OAhfor the number A, rather
bers.
than AH, so we
wouldn 't confuse
the
the
register
AH. We
will
ofien place a zero
before hex
numbers
in situations like this
that could be confusing. In fact, since it never hurts to
are, respectively,
By using
bers 9
number Ah with
and Fh
and Fh, you check the bottom and top of the
and OAh, although next
to each other, require
a hex number,
The machine-language version of this program contains a few more steps, but it is essentially the same as the BASIC version. It uses the CMP instruction, as well as a conditional jump instruction called JL {Jump ifLess Than). The program to take a single-digit hex number in the BL register and print it in hex is as follows:
a
MOV
AH, 02
3985:0102 88DA
MOV
DL.BL
zero before all hex
3985:0104 80C230
ADD
DL,30
numbers.
3985:0107 80FA3A
CMP
DL,3A
it is
place a
72
range.
different conversion
sen the correct place to switch between these two conversion schemes.
3985:0100 B402
to
two
schemes in the program. By using 9 and OAh, you confirm that you have cho-
place a zero before
good idea
numThe num-
the smallest and largest single-digit hex
,
5
3985:010A 7C03
JL
010F
3985: 01 0C 80C207
ADD
DL,07
3985: 01 0F CD21
INT
21
3985:0111 CD20
INT
20
The
G
Printing
Numbers
in
Hex
CMP instruction, as you saw before, subtracts two numbers (DL - 3Ah)
to set the flags, but
lOF instruction skips hex number in
does not change DL. So
it
to the
BL and
if
DL is
INT 21h instruction at
trace
through
this
less
than 3Ah, the JL
lOFh. Place a single-digit
example to get a better feeling
for
CMP and our algorithm to convert hex to ASCIL Remember to use either the G command with a breakpoint or the P command when you run the INT instructions.
0107
CMP
DL,3A
01 OA
JL
01 OF
01 OC
ADD
DL,07
01 OF
INT
21
X Jump if DL < 3Ah
—
<
figure 5-2: The JL instruction.
Using Rotate To Get the Upper Nibble The program works
for
any
steps to print a two-digit
which
see that
section,
you will encounter
you can
will use to isolate the
through the carry
flag.
a concept
RCL
In the
bits
known
—
by more than one
rotate
RCL
last
bit if you
which you
as a logical operation^
word
chapter you used the instruction to rotate
BL
left
by one
to the left
RCL BL, 1
bit.
You can
want, but you cannot simply write the in-
BL,2. For rotations by
count in the
this section,
the second of the two hex digits.
instruction rotates a byte or a
where the number one told the 80x86 struction
hex number. In
easily isolate the first, or higher, four bits. In the next
lower four
begin, recall that the
rotate
hex number, but we need a few more
We need to isolate each digit (four bits,
are often called a nibble) of this two-digit
you will
To
single-digit
hex number.
more than one
bit,
you must place a
CL register.
73
Assembly Language
Note
PC, Third Edition
for the
Although
RCL BL,2 isn't a legal 8088 instruction, it works just fine with
80286 and above processors found on most of today's computers. still some PCs with the older 8088s, it is best to write
the
Since there are
common
your programs for the lowest
The CL by the
register
used here in
is
much
the
denominator
same way
—
as the
the older 8088.
CX register
is
used
LOOP instruction to determine the number of times to repeat a loop.
The 80x86 than the
uses
CX
CL for the number of times
register,
The
eight-bit
shift
count.
CL
because
register
is
it
to rotate a byte or word, rather
makes no sense
more than
large
to rotate
enough
more than 16
to hold
your
times.
maximum
How does all this tie in with printing a two-digit hex number? The plan is to rotate the byte in DL four bits to the right. To do so, you will use a slightly different rotate instruction called SHR {Shift Right) Using SHR, you will be .
able to
move the upper four bits of your number to
the rightmost nibble (four
bits).
CF
DL
0110 1110 SHR DL, 1
Figure 5-3: The
You
want the upper four
also
becomes equal to enter
to the nibble
SHR DL,
the right.
1
bits,
,
bits
you
of DL
it
all
would move the byte
would move
times, the upper four bits will
bit
in
end up
all
were
DL one bit to
into the carry flag, while shift-
do
that three
shifted right into the lower four
have had zeros shifted into them.
You
one instruction by using the CL CL to four before the instruction SHR DL,CL, will ensure that
that shifting in
count. Setting
the entire register
(the highest, or leftmost, bit in DL). If you
while the upper four bits will
can do
set to zero, so that
are shifting into the right nibble. If you
your instruction
At the same time
ing z zero into bit 7
more
Instruction.
register as the shift
DL becomes equal to the upper hex digit. To see how this works, place 4 into 74
G
5
CL
and
5Dh
into
DL. Then
and
enter
trace
Numbers
Printing
through the following
in
Hex
SHR
instruction:
3985:0100 D2EA
SHR
DL.CL
DL should now be 05h, which can print
this digit
gether the pieces you have so a
number
BL
in the
is
the
with a program
register
far,
number 5Dh. Now you one used earlier. By putting to-
first digit in
like the
the
you can build the following program
and print the
3985 0100 B402
MOV
AH, 02
3985 0102 88DA
MOV
DL.BL
3985 0104 B104
MOV
CL,04
3985 0106 D2EA
SHR
DL.CL
3985 0108 80C230
ADD
DL,30
3985 010B 80FA3A
CMP
DL,3A
3985 010E 7C03
JL
0113
3985 0110 80C207
ADD
DL,07
3985 0113 CD21
INT
21
3985 0115 CD20
INT
20
first
hex
digit:
Using
AND to Isolate the Lower Nibble
Now
you can print the
that
how you bits
can
isolate
first
of the two
and print the second
digits in a
digit.
You
bits. It is
hex number,
will clear the
of your original (unshifted) number to zero, leaving
four
to take
let's
see
upper four
DL equal to the lower
easy to set the upper four bits to zero with an instruction called
AND. The AND instruction is one of the /o^/V^^/ instructions
—
those that have
their roots in formal logic.
In formal logic, false,
true
then
two
is
true, if
A must also
and zero
you can
"A
create
be
B andQ
false. If
are
both true." But
you take
as a truth table.
B
this statement, substitute
for false, then look at the various
what is known
if either
or
C
one
is
for
combinations of A, B, and C,
Here is the truth
table for
ANDing
bits together:
AND
F
T
F
F
T
T
F
T
AND
1
1
1
75
Assembly Language
for the
PC, Third Edition
Down the left and across the top are the values for the two bits. The results for
AND are in the table, so you see that AND gives 0. The AND instruction works on bytes and words by ANDing together the bits the
1
of each byte or word that are in the same position. For example, the statement
AND BL,CL successively ANDs bits and places the
BL.
result in
We
of BL and CL,
can make
bits 1, bits 2,
this clearer
and so on,
with an example in
binary, as follows:
10 110 10
1
1110 110
AND
110 10 Furthermore, by ANDing OFh to any number, you can
set the
upper four
bits
to zero, as follows:
11110 AND
1
1
11 1
1
7Bh OFh
=
10 11 Next you can put isolates the
OBh
this logic into a short
lower hex digit by
program that takes the number
ANDing OFh
to the
upper four
bits,
in
BL,
and then
You saw most of the details of this program when you printed the upper hex digit; the only new detail is the AND instrucprints the result as a character.
tion.
3985 0100 B402
MOV
AH, 02
3985 0102 88DA
MOV
DL,BL
3985 0104 80E20F
AND
DL,0F
3985 0107 80C230
ADD
DL,30
3985
01
0A 80FA3A
CMP
DL,3A
3985
01
0D 7C03
JL
0112
3985 010F 80C207
ADD
DL,07
3985 0112 CD21
INT
21
3985 0114 CD20
INT
20
Try
this
with some two-digit hex numbers in
the pieces together to print both digits.
of your number in
76
BL on
the screen.
BL
before
you move on
to
put
You should see the rightmost hex digit
5
Putting There
isn't
It
All
much
to
CI
Printing
Numbers
in
Hex
Together change when you put
all
the pieces together.
You need
only to change the address of the second JL instruction used to print the sec-
ond hex
digit.
The complete program
3985 :0100 B402
MOV
3985 10102 88DA
MOV
DL.BL
3985 10104 B104
MOV
CL,04
3985::0106 D2EA
SHR
DL.CL
3985::0108 80C230
ADD
DL,30
3985::010B 80FA3A
CMP
DL,3A
is
as follows:
AH, 02
3985::010E 7C03
JL
0113
3985::0110 80C207
ADD
DL,07
3985;:0113 CD21
INT
21
3985::0115 88DA
MOV
DL,BL
3985::0117 80E20F
AND
DL,0F
3985::011A 80C230
ADD
DL,30
3985::011D 80FA3A
CMP
DL,3A
3985::0120 7C03
JL
0125
3985::0122 80C207
ADD
DL,07
3985::0125 CD21
INT
21
3985::0127 CD20
INT
20
After you have entered this program, you will have to type U, to see the entire unassembled listing.
Note
of five instructions twice: the instructions
through 125h. In Chapter 7 you structions just once using a
new
at
will learn
that
U 100, followed by
you have repeated one
108h through 11 3h, and
how
1
set
lAh
to write this sequence of in-
instruction called
CALL.
Summary In this chapter, you learned
more about how Debug
the 80x86's binary format to a hex format
you can
translates
read.
numbers from
What did you add
to
your growing store of knowledge? First,
of the
you learned about some of the register (R) display.
These
two-letter flags
status bits give
tion about the last arithmetic operation.
you
you a
see
on the
right side
great deal of informa-
By looking
at the zero flag, for
77
Assembly Language
for the
PC, Third Edition
example, you could also
tell
whether the
result
of the
last
operation was zero.
found that you could compare two numbers with a
Next, you learned
how
to print a single-digit
information, you learned about the
number into
the upper digit of a two-digit hex
completed, you could print the Finally, the
the upper.
CMP instruction.
hex number.
SHR instruction,
You
Armed with this move
enabling you to
the lower four bits of BL. That
digit, as before.
AND instruction allowed you to isolate the lower hex digit from
By putting
a two-digit hex
all
these pieces together,
you wrote
a
program
to print
number.
We could have»continued on to print a four-digit hex number, but at this point, we would digit will
find ourselves repeating instructions. Before
hex number, you
know enough
—
78
to reading
try to print a four-
about procedures in Chapter
will learn
to write a procedure to
ready to learn about the assembler
Now, on
you
hex numbers.
a
do the
program
job.
7.
By then you
that will
Then, you will also
be
do much of your work.
{
I
I
ClH A
E
I
read characters from your keyboard.
You
I
I
P
I
T
I
Reading Characters In this chapter you will learn how to will build a small
board.
program that reads
a two-digit
hex number from the key-
F
r
Topics Covered Reading One Character
Reading a Single-Digit Hex Number Reading a Two-Digit Hex Number
Summary
^^m
Assembly Language
I
low
for the
that
PC, Third Edition
you know how
reverse the process
to print a byte in hex notation,
by reading two characters
and converting them
—hex
digits
you
—from
are going to
the keyboard
into a single byte.
Reading One Character The DOS INT 21h function call we have been using has an input function, number 1, that reads a character from the keyboard. When you learned about function calls in Chapter 4, you saw that the function number must be placed in the
AH
register before
INT 21h
enter
396F:0100 CD21
Olh
Place
you
INT 21h
OlOOh
INT
into
will see
an
at location
To
call.
1
INT
for
21h,
21
AH and type either G 1 02 or P to run this one instruction. All the blinking cursor. Actually,
is
try function
as follows:
DOS
has paused and
is
waiting
you press a key (don't do so yet). Once you press a key, DOS will place ASCII code for that character into the AL register. You will use this in-
until
the
struction later to read the characters of a hex
number. Right now,
happens when you press a key
DOS will return a
a semicolon
Fl
is
(;)
one of a
after
set
like the
of special keys with extended codes, which
table listing these extended codes in
DOS
returned
is
see
in
what
AL and
Debug's hyphen prompt.
from the keys representing normal ASCII
ently
keys,
F 1 key.
DOS treats differ-
characters.
(You
will find a
Appendix D.) For each of these
sends two characters, one right after the other. always zero, indicating that the next character
The
is
first
special
character
the scan code for a
special key.
To
read both characters, you
would have
to execute
INT 21h
twice.
But
in
our example, you read only the first character, the zero, and leave the scan code in
DOS. When Debug
finished with the
read characters, and the
first
character
from the Fl key, namely, 59, which Later,
when we develop
is
it
G
102 (or P) command,
read was the scan code
the
ASCII code
the Dskpatch program,
you
82
work with
the normal
ASCII
characters.
began to
left
behind
for a semicolon.
will begin to use these
extended codes to bring the cursor and function keys to will just
it
life.
Until then,
we
6
n
Reading Characters
Reading a Single -Digit
Hex Number Next you need
to reverse the conversion that
you transformed
a single-digit
in
Chapter
F.
To convert one character,
37h
(for
it
C
through
to a byte.
3985::0100 B401
MOV
3985::0102 CD21
INT
21
3985::0104 2C30
SUB
AL,30
3985:10106 3C09
CMP
AL,09
3985:10108 7E02
JLE
010C
3985::010A 2C07
SUB
AL,07
3985::010C CD20
INT
20
JLE {Jump
as
A through F). Here is a simple program that will read one ASCII
character and convert
Most of these
when
such
or D, from a hex character to a byte, you must subtract either 30h (for 9) or
5,
hex number to the ASCII code for one of the
through 9 or A through
characters in
you used
AH, 01
instructions should be familiar
ifLess than or Equal). In
AL is less than or equal
now, but there
your program,
is
one new one,
this instruction
jumps
if
to 9h.
from hex character to ASCII, you need to see the AL INT 20h is executed. Since Debug restores the registers when it executes the INT 20h, you will need to set a breakpoint, as you did in Chapter 4. Fiere, type G IOC, and you will see that AL will contain the hex
To
see the conversion
register just before the
number converted from Try typing some to see
a character.
characters, such as ^ or a lowercase d, that are not hex digits
what happens. You
will notice that this
program works
correctly only
when the input is one of the digits through 9 or the uppercase letters A through F. You will correct this minor failing in the next chapter when you learn about subroutines, or procedures. Until then, we will be sloppy and ignore error conditions. You will have to type correct characters for your program to work properly.
83
Assembly Language
for the
PC, Third Edition
Reading a Two-Digit
Hex Number digits isn't much more comphcated than reading one, but it many more instructions. Begin by reading the first digit, then place
Reading two hex does require its
hex value in the
plication, shift the bits) to
DL register and multiply by 16. To perform this multiDL register left four bits, which places a hex zero (four zero it
the right of the digit
CL set to
{Shift Left) instruction effect as
you just
four, does the trick is
read.
The
instruction
by inserting zeros
known
as
SHL DL,CL, with SHL
at the right. In fact, the
an arithmetic shift, because
it
has the same
an arithmetic multiplication by two, four, eight, and so on, depend-
ing on the
number
(such as one, two, or three) in
CF
CL
(See Figure 6-1).
DL
0110 1110 Figure 6-1: The
Finally,
ber in
SHL DL,1
with the
DL (the
instruction.
first digit
shifted over,
first digit * 16).
You can
in the following program:
84
3985 0100 B401
MOV
AH, 01
3985 0102 CD21
INT
21
3985 0104 88C2
MOV
DL.AL
3985 0106 80EA30
SUB
DL,30
3985 0109 80FA09
CMP
DL,09
3985 010C 7E03
JLE
0111
3985 010E 80EA07
SUB
DL,07
3985 0111 B104
MOV
CL,04
3985 0113 D2E2
SHL
DL.CL
3985 0115 CD21
INT
21
3985 0117 2C30
SUB
AL,30
3985 0119 3C09
CMP
AL,09
3985 011B 7E02
JLE
01 IF
3985 011D 2C07
SUB
AL,07
3985 011F 00C2
ADD
DL.AL
3985 0121 CD20
INT
20
add the second hex see
digit to the
and work through
all
num-
these details
6
Now that you
have a working program,
ary conditions to confirm that ditions, use the
such
Use
as
it is
a
good
idea to check the
Reading Characters
bound-
working properly. For these boundary con-
numbers 00, 09, OA, OF, 90, AO, FO, and some other number,
3C.
a breakpoint to run the
tion.
it is
G
(Make
sure
program without executing the
you use uppercase
letters for
INT 20h
instruc-
your hex input.)
Summary You have
finally
had
a
chance to practice what you learned
chapters without being flooded with
function (number
1) to
two-digit hex number.
grams with
all
the
new
information. Using a
in previous
new INT 21
read characters, you developed a program to read a
Along the way, we emphasized the need
to test pro-
boundary conditions.
We will wrap up Part
I
by learning about procedures
in the
80x86.
85
cIhjaIpItIeIr
1
Using Procedures to Write Reusable
Code In
this
chapter you will learn
how
to write small, general-purpose pieces of
code called procedures that you can use from anywhere
in
your program. Pro-
cedures are something you will use heavily in almost any program you write.
In this process you will also learn about the stack, and you will build a
hex-input routine that prevents you from typing invalid
digits.
new
Topics Covered Writing Procedures
How CALL Works: The
Stack and Return Addresses
PUSHing and POPping Data Reading Hex Numbers with More Class
Summary
Assembly Language
In
PC, Third Edition
for the
the next chapter,
we
will discuss
MASM,
the
macro assembler, and you
^^^w^/y language. But before leaving Debug, you
will begin to use
will
one last set of examples and learn about subroutines and a special place
numbers
look
at
to store
called the stack.
Writing Procedures A procedure
a
is
list
of instructions that can be executed from different places
in a program, rather than having to repeat the
place they're needed. In call
BASIC
them procedures for reasons
You move
such
lists
that will
become
and from procedures by using
to
procedure with one instruction, CALL.
same
list
of instructions
are called subroutines, but
You
at
each
we
will
clear later.
You
a pair of instructions.
call a
return from the procedure with a
i^fT" instruction.
Here
a simple
is
BASIC program,
written in QBasic, that you will later re-
write in machine language. This program calls a subroutine ten times, each
time printing a single character, starting with A and ending with J,
as follows:
DIM SHARED A A = &H41 FOR
'ASCII for 'A'
=
I
1
TO 10
DoPrint A = A + NEXT
1
I
SUB DoPrint
PRINT CHR$(A); END SUB
QBasic
is
actually
much
that were shipped with versions of
sions of
BASIC
and you had
required line numbers in front of each line of the program,
to use the
code. Since the older
below, here
is
GOSUB and RETURN commands to write the same
BASIC
the above
using line numbers.
88
GWDOS before DOS 5.0. Earlier ver-
simpler than older versions of BASIC, such as
BASIC,
looks
more
like the
program rewritten
machine code we
in a primitive version
will write
of BASIC,
n
7
10 A = &H41
20 FOR
=
I
'ASCII for
Using Procedures to Write Reusable Code
A'
TO 10
1
30 GOSUB 1000
40 A = A + 50 NEXT
1
I
60 END
1000 PRINT CHR$(A) 1010 RETURN
common when BASIC programs
In this case the subroutine follows a practice
needed
line
numbers, by beginning
added
structions to be
of the subroutine.
to the
You
at line 1000 to leave room for more inmain program without affecting the line number
will
have to do the same with your machine-language
procedure since you cannot
move machine-language programs easily (this won't
be a problem once you
200h,
far
You
1000 with the instruction
CALL
The CALL sets
it is
put the machine-language subroutine
will
away from the main program
location 200h.
assembler in the next chapter, so
start to use the
only a temporary problem).
at
lOOh.
200h, which
calls
at
also replace
GOSUB
the procedure at
memory
You will
IP to 200h, and the 80x86
starts
executing the
instructions at 200h.
The FOR-NEXT loop of the BASIC program (as you saw in Chapter 4) can be written as a LOOP instruction. The other pieces of the main program (except for the INC instruction) should be familiar. They are as follows: 3985:0100 B241
MOV
DL,41
3985:0102 B90A00
MOV
CX,000A
3985:0105 E8F800
CALL
0200
3985:0108 FEC2
INC
DL
3985: 01 0A E2F9
LOOP
0105
3965:0100 CD20
INT
20
The the
first
instruction places 41 h (ASCII for A) into the
INT 21 h
instruction prints the character given
The INT 21h
instruction itself
cedure at location 200h. register.
That
alphabet.
is,
it
is
located
INC DL,
the
3985:0200 B402
MOV
AH, 02
3985:0202 CD21
INT
21
3985:0204 C3
RET
register,
new
enter at
because
by the ASCII code
some distance away,
adds one to DL, setting
The procedure you should
DL
in
instruction, increments the
DL
DL.
in the pro-
DL
to the next character in the
200h
is
as follows:
89
Assembly Language
for the
PC, Third Edition
02h in AH tells DOS to print the character in DL when you execute the INT 21h instruction. RET is a new instruction that returns to the Recall that the
first
instruction
Type
G
(LOOP)
to see the
following the
CALL
in
your main program.
output of this program, then single-step through
how it works (remember to the INT 21 instruction). 0105: 0108:
use either a breakpoint or the
P command
to see
run
to
CALL LOOP
MOV
0200:
AH,02
0202: INT
21
0204: INC
DL
RET
0206:
Figure 7-1: The
it
CALL and RET instructions.
How CALL Works: The
Stack
and Return Addresses The CALL instruction where it
so the
sees the
80x86
RET
memory known registers that
in
will
your program needs to save the return address some-
know where
to
resume executing instructions when
instruction. For the storage place as the stack.
For tracking what
is
itself,
on the
there
is
a portion of
stack, there are
you can see on the R display: the SP {Stack Pointer)
register,
two
which
points to the top of the stack, and the SS {Stack Segment), which holds the
segment number. In operation, a stack for the 80x86
is
just like a stack
where placing a tray on the top covers the the stack
90
is
the
first
to
come
off,
so another
of trays in a
trays underneath.
name
for a stack
The is
cafeteria,
last tray
LIFO,
on
for Last
7
This order, LIFO,
In, First Out.
is
precisely
turn addresses after you
make
396F:0100 E8FD00
CALL
0200
0300
396F:0200 E8FD00
CALL
396F:0203 C3
RET
396F:0300 E8FD00
CALL
396F:0303 C3
RET
396F:0400 C3
RET
O
nested
Using Procedures to Write Reusable Code
what you need
CALLs
for retrieving re-
like the following:
0400
The instruction at lOOh calls one at 200h, which calls one at 300h, which calls one
at
400h, where you
finally see a return
(RET)
turns to the instruction following the previous the
80x86 resumes executing
RET stack.
instruction at 303h,
topmost return address off the
same path backward
Try entering
a
as the
program
and
CALLs
like the
through the program to see
RET
re-
instruction, at 300h, so
But there
it
encounters a
pulls the next oldest address (203h) off the
So the 80x86 resumes executing instructions
RET pops the
cess
instructions at 303h.
which
instruction. This
CALL
at
203h, and so on. Each
stack, so each
RET
follows the
did forward, see Figures 7-2 and 7-3.
preceding one. Use multiple
calls,
and
trace
how the calls and returns work. Although the pro-
may not seem very interesting right now, there are other uses for this stack, a good understanding of how it works will come in handy. (In a later
chapter,
you
will
look for the stack in memory.)
PaSHing and POF>ping Data The
stack
is
a useful place to store
carefiil to restore
the stack before a
words of data
for a while, provided
you
are
RET instruction. You have seen that a CALL
instruction /)«5/;« the return address (one word) onto the top of the stack, while
91
Assembly Language
a
for the PC, Third Edition
RET instruction />o/)^ this word off the
register,
and exposes the word
same thing with the
that
instructions
top of the stack, loads
was lying underneath
PUSH
it.
it
into the IP
You can do
and POP, which allow you
to
the
push
and pop words.
Address
Stack
0098 SPrioo>
0100
0203
0102
0203
0104
Figure 7-2: The stack just before executing the
It is
CALL 400 instruction.
often convenient to save the values of registers at the beginning of a pro-
cedure and restore them at the end, just before the are free to use these registers in as
you
any way you
like
RET instruction. Then you
within the procedure,
as
Programs are
built
from many
levels
procedures at the next level down.
procedure and restoring them
of procedures, with each
By
level calling the
saving registers at the beginning of a
at the end,
you remove unwanted
interactions
between procedures at different levels, making your programming much
You will see more about saving and restoring registers
92
long
restore their values at the end.
in
Chapter
13,
easier.
when we
n
7
discuss restores
modular design. Following
is
Osing Procedures to Write Reusable Code
an example (don't enrer
it)
that saves
and
CX and DX:
396F:0200
51
PUSH
396F:0201 52
PUSH
DX
396F:0202 B90800
MOV
CX,0008
396F:0205 E8F800
CALL
0300
396F:0208 FEC2
INC
DL
396F:020A E2F9
LOOP
0205
CX
396F:020C 5A
POP
DX
396F:020D 59
POP
CX
396F:020E C3
RET
Address
SPI98
>
Stack
0098
0303
0100
0203
0102
0203
0104
Figure 7-3: The stack just after executing the
Notice that the
POPs
CALL 400 instruction.
are in reverse order
from the PUSHes, because a
removes the word placed most recently on the is
stack,
POP
and the old value of DX
on top of the old CX.
93
Assembly Language
for the PC, Third Edition
Saving and restoring
CX and DX allows you
procedure that begins procedure that
at
change these
registers in the
200h, but without changing the values used by any one.
calls this
to
Once you have
these registers to hold /oc^/ variables
saved
—
variables
CX and DX,
you can use
you can use within
this proce-
dure without affecting the values used by the calling program.
You will as
you
often use such local variables to simplify
your procedures changing any of the will
become
registers
clearer in the next example,
number. Unlike the program
in
tasks.
to
As long
worry about
used by the calling program. This
which
Chapter
programming
you won't have
are careful to restore the original values,
6,
is
a procedure to read a hex
your new program
now
will
allow only valid characters such as A, but not K.
Reading Hex Numbers with More Class Next, you can create a procedure that keeps reading characters until
one that can be converted
want
to display
ing a
new INT 21h
pass
it
function,
8h
into the
INT
The ASCII code for A screen.
Using
echoing them until
which
it
will
acter to a
94
number
(4 1 h)
1
through your input us-
8, that reads a
character but does not
(display) characters only if they
21
is
now in the AL register,
but the A didn't appear
your program can read characters without
reads a valid hex digit (0 through 9 or
then echo.
hex number
and Fh. You do not
will sift
02.
this function, it
The
is
receives
AH register and run through this instruction, typ-
A just after you type G
3985:0100 CD21
on the
number between
onto the screen. That way you can echo
are valid. Place
ing an
to a hex
any invalid characters, so you
it
A
through
F),
procedure to do this and to convert the hex char-
as follows:
3985 0200 52
PUSH
DX
3985 0201 B408
MOV
AH, 08
3985 0203 CD21
INT
21
3985 0205 3C30
CMP
AL,30
3985 0207 72FA
JB
0203
3985 0209 3C46
CMP
AL,46
O
7
3985:0206 77F6
JA
0203
3985:0200 3C39
CMP
AL,39
3985:020F 770A
JA
0216
3985:0211 B402
MOV
AH, 02
DL.AL
3985:0213 88C2
MOV
3985:0215 CD21
INT
21
3985:0217 2C30
SUB
AL,30
3985:0219 5A
POP
DX
3985:021A C3
RET
3985:0216 3C41
CMP
3985:0210 72E4
JB
0203
3985:021F 6402
MOV
AH, 02
3985:0221 88C2
MOV
DL.AL
3985:0223 CD21
INT
21
3985:0225 2C37
SUB
AL,37
3985:0227 5A
POP
DX
3985:0228 C3
RET
The procedure to see if it
read
is
is
AL (with the INT 2 h at 203h) and checks CMPs and conditional jumps. If the character just
reads a character in
valid with the
and JB
is
INT 21h reads another character.
Jump ifBelow. Both
whereas the JL instruction used
line
211h, you
just subtract the ter,
know
that
the procedure.
treat the
The
you have
a valid digit
RET
both
as
as
unsigned
num-
signed numbers.)
between
and return the
(JA \sjump
and
result in the
9, so
you
AL regis-
DX register, which you saved at the beginning of
process for hex digits
two
tice that there are
two numbers
earlier treated
code for the character
remembering to pop the
A through F
is
much
instructions in this procedure.
had more, or you could have had test
1
not a valid character, the conditional jump instructions sends the 80x86
ifAbove,
By
Reusable Code
AL,41
back to location 203, where the
bers,
CIsing Procedures to Write
just one.)
Here
is
the same.
No-
(You could have
a very simple
program
to
the procedure:
3985:0100 E8FD00
CALL
0200
3985:0103 CD20
INT
20
As you have done the P
before, use either the
G command with a breakpoint, or use
command. You want to execute the CALL 200h instruction without INT 20h instruction, so you can see the registers just before the
executing the
program terminates and the
You
registers are restored.
will see the cursor at the left side
character.
Type
k,
which
of the screen, waiting patiently for a
isn't a valid character.
Nothing should happen. Now,
93
Assembly Language
for the PC, Third Edition
You should
type any of the uppercase hex characters.
AL and the character itself echoed on
value in
with the boundary conditions: acter just after 9),
and so on.
to read a two-digit hex
7' (the character before zero), 0, 9,
Now that you have this procedure,
number with
3985 0100 E8FD00
CALL
3985 0103 88C2
MOV
DL.AL
3985 0105 B104
MOV
CL,04
3985 0107 D2E2
SHL
DL.CL
3985 0109 E8F400
CALL
0200
3985 010C 00C2
ADD
DL.AL
3985 010E B402
MOV
AH, 02
3985 0110 CD21
INT
21
3985 0112 CD20
INT
20
You can run
this
see the character's
error handling
is
(the char-
the
program
0200
program from DOS, since
it
number number you
reads in a two-digit hex to the
in.
Aside from the procedure, your main program sion
':'
fairly straightforward.
and then displays the ASCII character that corresponds typed
hex
the screen. Test this procedure
you wrote
in the last chapter,
tions to read characters.
You
is
much
simpler than the ver-
and you have not duplicated the
did add error handling, even
the procedure; error handling ensures that the
if it
instruc-
did complicate
program accepts only
valid
input.
You can
also see the reason for saving the
main program dure use
at
200h
stores the
to
hex number
change DL.
On
in
DX register in
DL,
so
the procedure.
The
you don't want your proce-
the other hand, the procedure at
200h must
DL itself to echo characters. So, by using the instruction PUSH DX at the
beginning of the procedure, and problems.
be very
From now on,
strict
POP DX at the end, you saved yourself from
to avoid complicated interactions
about saving any
registers
between procedures,
used by a procedure.
Summary Your programming
is
becoming more
sophisticated.
You have
learned about
procedures, which enable you to reuse the same set of instructions without
96
n
7
rewriting
them each
time.
CALL stores a return
so
learned
how
also discovered the stack
address on the top of the stack, while a
on the top of the
returns to the address
You You
You have
Using Procedures to Write Reusable Code
to use the stack for
more than
instruction) at the
in a procedure.
just saving return addresses.
By
write,
end of each procedure, you avoided unwanted
you can
registers are
CALL
armed with
this
to read
hex numbers
—
is
instruction)
registers in
POP
interactions
procedures that
other procedures without worrying about which
used within the other procedure.
Finally,
here
PUSH
restoring the registers (with a
between procedures. By always saving and restoring
you
that a
stack.
used the stack to store the values of registers (with a
you could use them
and seen
RET instruction
similar to
knowledge, you moved on to build a better program
this time,
one you
The program you built when you begin to develop
with error checking.
will use in later chapters,
your Dskpatch program.
Now you are ready to move on to Part II, where you will learn how to use the assembler.
gram
to
The
next chapter covers the use of the assembler to convert a pro-
machine language. You
will also see that there will
room between procedures, cedure way up at location 200h. to leave
as in this chapter,
not be any reason
when you put your
pro-
97
R
Assembly Language
4
63T57r9A|75|B6|D2|FD
95 |8A
35
|6F^
#'
|47
|63
4A
C
I
H A I
I
Welcome
P
I
T
I
E
I
to
the Assembler In this chapter you will learn how to build programs using either the Microsoft Macro Assembler or the Borland Turbo Assembler. Building programs with the assembler is much easier than building them with Debug. You will learn how to assemble and link programs and how to comment your programs and use labels so they are easy to understand.
R
Topics Covered Building a Program without
Debug
Creating Source Files Uniting Your Program
Looking
at Writestr in
Using
Debug
Comments
Using Labels
for
Summary
Code
Assembly Language
/\t
PC. Third Edition
for the
long
last
you
are ready to
DOS
meet the assembler, a
make your programming much
simpler.
monic, human-readable instructions
From now
directly,
program
that will
on, you will write
mne-
using the assembler to turn your
programs into machine code. This chapter and the next will be somewhat heavy with but learning these details will be well worth the
bler,
how to
use the assembler,
you will
get back
on course
details
effort.
on the assem-
Once you know
in learning
how to write
assembly-language programs.
Building a
Program
without
Debug
Up
you have typed only
to this point,
structions.
Now that you are about to
grams without create text, or
it,
you
will
files
—
Begin by creating a source file
named
is
You will
the
Debug
the
name
file
MOV
AH, 02
MOV
DL,2A
396F:0104 CD21
INT
21
396F:0106 CD20
INT
20
DOS's
named WRITESTR.ASM
bler source
file).
Here,
as
(the extension
1:
.CODE
MOV
AH,2h
MOV
DL,2Ah
3.
.ASM means
with Debug, lowercase works just
but we will continue to use uppercase letters number 1 (one) and the lowercase letter
.MODEL SMALL
102
program you
To
built
refresh
and
your
Edit, to enter the following lines of code into
case,
the
for the
version:
396F:0102 B261
a file
for the text version of an assembly-
create a source
396F:0100 B402
a text editor, such as
to write pro-
containing assembly-language instructions.
Writestr (short for Write Star) back in Chapter
memory, here
Use
then your program in-
Debug behind and
have to use either an editor or a word processor to
human-readable
language program.
DEBUG and
leave
this
is
an assem-
as well as
upper-
to avoid confiision between
— n
8
INT
21h
INT
20h
Welcome
to the
Assembler
END
This
is
the
same program you created
essary changes in the
and
tells
after
numbers
is
3,
all
numbers
are decimal.
any hexadecimal number
(see
You
but
an h
the assembler that the
mal. Unlike Debug, which assumes all
Chapter
additions. Notice that there
program. This h
sembler assumes
in
it
contains a few nec-
after
each hex
numbers
number
are in hexadeci-
are in hexadecimal, the as-
tell it
otherwise by placing an h
Figure 8-1).
The assembler can become conftised by numbers, such as ACh, that look like a name or an instruction. To avoid this, always type a zero before a hex niunber that begins with a letter. For example, type OACh not ACh.
This
MOV
a label
DL,ACh
This
MOV
is
is
a
number
DL,OACh
The
tells
MASM
that this is a
number
Figure 8-1: Put a zero before hexadecimal numbers starting with a assembler will treat the
llfM!
letter,
otherwise the
number as a name.
103
h
Assembly Language
for the
PC, Third Edition
The following program demonstrates what happens when you assemble a pro-
ACH rather than OACH.
gram with
SMALL
MODEL CODE
MOV
DL.ACh
INT
20h
END
The output
is
as follows:
C>ML /C TEST. ASM
Microsoft
(R)
Macro Assembler Version 6.00
Copyright
(0)
Microsoft Corp 1981-1991.
All rights reserved.
Assembling: test. asm test.asm(3): error A2006: undefined symbol
:
ACh
C>
Definitely not encouraging. But changing the
ACh
OACh
to
will satisfy the
commands in the assembler program. We used tabs to align everything neatly and to make the source text more readable. Compare the program you entered with the following: assembler. Also notice the spacing of the
.MODEL SMALL .CODE
MOV AH,2h MOV DL,2Ah INT 21 INT 20h
END
A bit of a mess;
the assembler does not care, but
we
do.
Now let's return to the three new lines in your source file. The three new lines are
all
directives (also
sometimes cdWtd pseudo-ops, or pseudo-operations). They
are called directives because they supply information
sembler, rather than generate instructions.
of the source Later on, let's
you
file
will see that
put aside any
on the assembler.
104
so the assembler
END
knows
is
fijrther discussion
The
it is
and directions
to the as-
END directive marks the end
finished
when
also useful in other ways.
it
sees
But
an
END.
right
now,
of it or the other two directives and focus
8
Welcome
CI
to the
Assembler
Creating Source Files Even though you have entered the assembler can use source
you
are using a
disk
files
culprit.
word
WRITESTR.ASM,
of
lines
more consideration before we move on
to actually assemble
using only the standard
mind
ASCII
one
our program. The
that not
characters. Microsoft
Word is one such
For such word processors, use the non-document, or unformatted,
mode when you
save your
files.
Before you try assembling WRITESTR.ASM,
DOS,
is
ASCII characters only. If all word processors write
that contain standard
files
processor, bear in
there
make sure it is still ASCII. From
type:
C>TYPE WRITESTR.ASM
You should
see the
characters in your
same
text
file,
line after the
word processor
You
will
DOS
and
need to read
this
before 6.0, or Borland's If
you
END statement
5
(available in
you entered
which the assembler will
to use a different editor or
gram
as
later) will
and
your
in
programs.
work well
file.
of
MASM
"ML /C WRITESTR.ASM",
MASM followed by the
finally a semicolon:
If you are using Borland's
file
"MASM
You
DOS
will also
Edit pro-
a version
of
files.
MASM
Note
than 6.0, you will need to
files.
you
The
you may have
for creating source
note if you are using Turbo Assembler.
are using an older version
like
If you see strange
treat as errors)
to enter
use a slightly difi^erent syntax for assembling
mand mand
it.
program (many word processors put additional formatting
information into the
need a blank
you entered,
Instead of using a
will
name (without WRITESTR;".
com-
need to use the comthe
.ASM
Turbo Assembler, you will need to
extension),
use a slightly
command like "ML /C WRITESTR.ASM", you will need to use the command TASM followed by the file name (without the .ASM extension), and finally a semicolon: "TASM WRITESTR;". different syntax for assembling
files.
Instead of using a
105
Assembly Language
Now,
for the
let's
PC, Third Edition
begin to assemble Writestr.
sembler, type
(If you are
using Borland's
Turbo As-
"TASM WRITESTR;" instead of "ML /C WRITESTR. ASM".)
WRITESTR. ASM
C>IIL /C
Microsoft
(R)
Macro Assembler Version 6.00
Copyright
(C)
Microsoft Corp 1981-1991.
All rights reserved.
Assembling: writestr. asm
C>
You are not finished yet. At this
point, the assembler has
WRITESTR.OBJ, which you will file,
called
a lot of
an objectfile.
It
find
on your
disk.
produced a
This
is
file
called
an intermediate
contains the machine-language program, along with
bookkeeping information used by another
DOS
program
called the
create an
EXE ver-
Linker.
Linking Your Program Right now, you want the linker to take your sion of
it.
Link
WRITESTR.OBJ
OBJ
file
and
by typing the following:
C>LINK WRITESTR; Microsoft
(R)
Segmented -Executable Linker
Copyright
(C)
Microsoft Corp 1984-1991.
Version 5.13
All rights reserved.
LINK
:
warning L4021
LINK
:
warning L4038: program has no starting address
no stack segment
:
C>
Even though the
linker
warns you that there
need one right now. After you learn will see
ing a COM
file
(you
will see
Now you have your EXE file, create a
COM version, which
why you need
Writestr.
106
to
is
no stack segment, you don't
add more of the trappings, you
why you might want a stack segment. You also can ignore the warning
about no starting address, which
see
how
all
of these
is
not important here since you will be creat-
why later). but is
this
just
steps.
still
isn't
the
last step.
Next, you need to
what you created with Debug. Later you will For now, you
will create a
COM version of
8
For your
name
you
final step,
will use a
implies, converts an
EXE
difference between
EXE
and
file
now
Welcome
to the
program EXE2BIN.EXE. Exe2bin,
COM, or binary (bin)
to a
COM
ences until Chapter 11. For
n
files,
but
we won't
just create the
as its
There
file.
Assembler
is
a
deal with the differ-
COM
file
by typing the
following: C>EXE2BIN WRITESTR WRITESTR.COM C>
The all
response did not
of the Writestr
you very much. To see whether Exe2bin worked, you have created so far.
tell
files
list
C>DIR WRITESTR.* Volume in drive C has no label Volume Serial Number is 191C-8737
Directory of C:\SOURCE\ASM
WRITESTR ASM
73 10-13-92
1:51p
WRITESTR OBJ
107 10-13-92
2:04p
WRITESTR EXE
520 10-13-92
2:07p
WRITESTR COM
8 10-13-92
2:12p
4 file(s)
708 bytes
1179648 bytes free C>
Type
writestr to
properly
DOS The
run the
(recall that it
reports for the
results
COM version and verify that your program functions
should print an asterisk on your screen).
first
may seem
a
three
little
files
become much
clearer
a bit.
anticlimactic, because
back where you were in Chapter It will
may vary
3.
You
when you
The exact sizes
are not;
it
looks as though you are
you have gained
a great deal.
you
deal with calls again. Notice that
never once had to worry about where your program was put in memory, as
you did about IP Very soon you
in
Debug. The addresses were
will appreciate this feature
gramming much
easier.
space by placing your
200h.
You
For example,
main program
all
taken care of for you.
of the assembler:
recall that in the last at
1
it
will
make
OOh and the procedure you
will see that using the assembler allows us to place the
immediately
after the
program looks
to
main program without any gap.
pro-
chapter you wasted
First, let's see
called at
procedure
how your
Debug.
107
.
Assembly Language
PC, Third Edition
for the
Looking at Writestr To
see
how Debug
Debug
in
reconstructs your program from the machine code of
WRITESTR.COM,
COM
read your
file
into
Debug and unassemble
it,
as
follows:
C>DEBUG WRITESTR COM -U
397F:0100 B402
MOV
AH, 02
397F:0102 B22A
MOV
DL,2A
397F:0104 CD21
INT
21
397F:0106 CD20
INT
20
This
is
exactly
what you had
WRITESTR.COM. The END file
did not
These
make
directives
it
through
do not appear
program because they lot
of bookkeeping
are for
and the two
all.
3.
This
is all
Debug
lines at the start
What happened
in the final
of some extra
your job. You
learn about segments in
Using
Chapter
to
sees in
of your source
them?
machine-language version of the
bookkeeping only. The assembler takes care of a
at the cost
directives to simplify
when you
at
in
lines.
will see
Chapter
You will make good
how
use of
they affect your program
1 1
Comments
Because you are no longer operating directly with Debug, you are free to add
more
to
your program that the assembler sees but won't pass on to the 80x86.
Perhaps the most important additions you can make are comments, which are invaluable in
comments
BASIC
making a program clear. In assembly language programs, you place
after a
or the
//
semicolon, which works like a single quotation
in
C++. The assembler ignores anything on the
semicolon, so you can add anything you want. If you add brief
program you
will see quite
program without having
108
an improvement
to think
mark
(')
comments
to
your
—you can understand
back and remember what each
in
line after a
line
this
means.
8
MODEL
n
Welcome
to the
SMALL
Assembler
Many programmers
CODE
believe that well-
written code doesn
MOV
AH,2h
jSelect DOS function 2, character output
MOV
DL 2Ah
;Load the ASCII code for
INT
21h
;Print it with INT 21h
code
INT
20h
;And exit to DOS
understand. Not!
,
'*'
't
need comments
to be printed
because well-written is
easy to
WhiU you may END
be
able to understand
what some code does without comments,
you may not be able
Using Labels
for
Code
to figure
oufw\\Y
the code
is
doing
what it is. Good
To round
off this chapter,
let's
take a look at labels,
which
book-
are another
comments should your code
Until now, you had to give a specific address a
program
to another with
when jumping from one
instructions.
part of
one of the jump commands. In everyday program-
ming, inserting new instructions forces you to change the addresses
why
therefore say
keeping feature of the assembler that make programming smoother.
in
is
doing
something, not just
what
it's
doing.
jump
—
The assembler takes care of this problem with Libels names you any instructions or memory locations. A label takes
give to the addresses of
the place of an address. label
As soon
as the
assembler sees a
with the correct address before sending
it
on
label,
to the
it
replaces the
80x86,
as in
Figure 8-2.
DIGIT1:
Figure 8-2: The assembler substitutes addresses for
labels.
109
:
Assembly Language
for the PC, Third Edition
Labels can be
up
to 3
1
characters long
and can contain
any of the following symbols: a question mark (@), an underline (_), or a dollar sign (0
through
As a
9),
and
a period
can be used only
practical example, let's take a look at
reads a two-digit hex
The
old version
is
number.
It
MOV
AH, 01
INT
21
3985 0104 88C2
MOV
DL.AL
3985 0106 80EA30
SUB
DL,30
3985 0109 80FA09
CMP
DL,09
3985 010C 7E03
JLE
0111
3985 010E 80EA07
SUB
DL,07
3985 0111 B104
MOV
CL,04
3985 0113 D2E2
SHL
DL.CL
3985 0115 CD21
INT
21
3985 0117 2C30
SUB
AL,30
3985 0119 3C09
CMP
AL,09
3985 011B 7E02
JLE
011F
3985 011D 2C07
SUB
AL,07
3985 011F 00C2
ADD
DL.AL
3985 0121 CD20
INT
20
fiinction of this
ments and .MODEL
it
may
labels
They cannot
an ^f symbol
(.),
start
with a digit
as the first character.
your program from Chapter 6 that
JLE 0111 and JLE
11 F.
as follows:
3985 0102 CD21
your mind,
numbers, and
letters,
a period
contains two jumps,
3985 0100 B401
The
($).
(?),
program
is
not obvious. If
take a while for
makes
this
you
to
this
program
understand
program much
easier to
it
is
again.
not fresh in
Adding com-
understand
as follows:
SMALL
.CODE
character input
MOV
AH,1h
;Select DOS function
INT
21h
;Read a character, and return ASCII code in AL
MOV
DL.AL
;Move ASCII code into DL
SUB
DL,30h
;Subtract 30h to convert digit to
CMP
DL,9h
;Was it a digit between
JLE
DIGIT1
;Yes, we have the first digit
SUB
DL,7h
;No,
MOV
CL,4h
;Prepare to multiply by 16
SHL
DL.CL
;Multiply by shifting, becomes upper four bits
1,
9
-
and 9? (four bits)
subtract 7h to convert letter A
-
F
DIGIT1
110
.
O
8
Welcome
to the
Assembler
I
INT
21h
SUB
AL,30h
CMP
AL,9h
;Is it a digit
JLE
DIGIT2
;Yes,
SUB
AL,7h
;No,
;Get next character ;
Repeat conversion 9?
so we have the second digit
subtract 7h
DIGIT2:
ADD
DL.AL
;ADD second digit
INT
20h
;And exit
END
The
labels here,
because a colon
DIGIT 1 and DIGIT2, (:)
NEAR\\2iS to do with segments, which the
are of a type
appears after the labels
when
we will
known
7V£4^ labels, The term
as
they are defined.
cover in Chapter
1 1
along with
MODEL, and CODE directives. If you assembled the preceding program
and then unassembled Oil Ih and
DIGIT2
it
with Debug, you would see
DIGIT 1
replaced by
replaced by OllFh.
Summary This has been quite a chapter. In a way, world.
it is
as if you
have stepped into a
new
The assembler is much easier to work with than Debug, so you can now
begin to write
real
programs because the assembler does
much of the book-
keeping for you.
What have you learned here? You began by learning how to create a source file and then you went through the from an
OBJ
file
to
steps
of assembling, linking, and converting
an EXE, and then a
COM
file,
using a simple program
The assembly language program you created contained a few
from Chapter
3.
directives that
you have never seen
before, but
which will become
you have become more comfortable using the assembler. In
MODEL, CODE,
and
fact,
familiar once
you will place
END directives in all of your programs from now on,
because they are needed, even though
Chapter
it
it
will
not be apparent
why
until
1 1
Ill
Assembly Language
for the
PC, Third Edition
You may have wondered how you survived without comments. Comments add so much to the readability of programs that you should not skimp on them. Next, you learned about comments.
Finally able.
you learned about
You
will use
book. Let's
all
move on
cedures easier to use.
112
labels,
which make our programs even more read-
of these ideas and methods throughout the to the next chapter to see
how
the assembler
rest
of
this
makes pro-
(
|c|h|a|pDEBUG TEST_SEG.EXE R
AX=0000
BX=0000
CX=0004
DX=0000
SP=0000
DS=3985
ES=3985
SS=3995
CS=3995
IP=0000
MOV
3090:0000 B44C
The
stack
is
BP=0000
SI=0000
DI=0000
NV UP EI PL NZ NA PO NC
AH,4C
now at 3995:0, which is the start of your program (CS:0). This is You do not want the stack anywhere near your program's code.
very bad news.
Since the stack pointer
is
at SS:0,
it
has no
room to grow (since the stack grows
Always declare a stack segment with
.STACK in EKE programs.
down in memory). For these reasons, you must declsu^c a stack segment for EXE programs.
Getting back to the two-segment example, notice that the Stack Segment (SS) is
segment number 3997
Code Segment (CS)
is
at
lower in memory. Since
unassembling starting
INT
at
(this will
probably be different for you), while our
segment 3995
—two
less
than SS, or just 32 bytes
we did not put any data into the stack segment, CS:0 will show our program (MOV AH,4C and
21) followed by whatever happened to be in memory.
145
Assembly Language
for the
PC, Third Edition
u cs:e
3995:0000 B44C
MOV
AH, 40
3995:0002 CD21
INT
21
3995:0004 65
DB
65
3995:0005 2028
AND
[BX+SI],CH
3995:0007 59
POP
CX
3995:0008 2F
DAS
3995:0009 4E
DEC
SI
3995:000A 293F
SUB
[BX],DI
You will almost Debug listing.
certainly see different instructions after the
The Program Segment
INT 21h
in this
Prefix
(PSP) The
"scratch area "
is
actually called a
PSP (Program Segment Prefix) and contains information for use by
DOS.
In looking at the register display, you
contain 3985h, lOh
registers
less
ment 3995h. Multiplying by 16 there are
lOOh
(or
may
have noticed that the ES and
than the beginning of the program to get the
number of bytes you can
256) bytes before your program
scratch area placed at the beginning of a
COM
starts.
This
is
DS
at seg-
see that
the
same
file.
In other words, do
not assume you can
Among other things,
make
acters typed after the
use
ofthis
area.
this
256 byte PSP
at the start
name of the program,
of programs contains char-
starting at
80h from the
start
of
the PSP. For example: C>DEBUG TEST_SEG.EXE And now for some characters you will see in the memory dump D DS:8e
146
And now for so
3985:0080
39 20 41 6E 64 20 6E 6F-77 20 66 6F 72 20 73 6F
9
3985:0090
6D 65 20 63 68 61 72 61-63 74 65 72 73 20 77 65
me characters we
3985:00A0
27 60 60 20 73 65 65 20-69 6E 20 74 68 65 20 6D
'11 see in the m
3985:0060
65 6D 6F 72 79 20 64 75-6D 70 0D 20 6D 65 6D 6F
emory dump, memo
3985:0000
72 79 20 64 75 6D 70 0D-00 00 00 00 00 00 00 00
ry dump
n
11
The
byte says you typed
first
39h
(or 57) characters, including the first space
TEST_SEG.EXE. You won't use this information helps show why you might want such a large PSP. after
The PSP
also contains information that
gram, with either the
INT 20h
For reasons that are not
EXE
program. The
4Ch
You should
of the PSP.
uses
when
exiting
from
it
a pro-
INT 21h, function 4Ch instructions. INT 20h instruction expects the CS register it
does for a
COM program but not for
(INT 21h, ftinction 4Ch) was added to of version 2.00 to make it easier to exit from EXE
exit ftinction
DOS with the introduction programs; function
DOS
book, but
in this
or the
clear, the
of this PSP, which
to point to the start
an
Segments
CS register to point to the start ftinction 4Ch from now on to exit pro-
does not expect the
use
INT 21h,
grams.
The code for COM files always starts at an offset of 1 OOh in the code segment to leave room for this 256-byte PSP at the start. This is unlike the EXE file, which had
its
code
start at
IP = 0000, because the code segment started lOOh
bytes after the beginning of the area in
In the early days of
memory.
DOS, most programs were
written as
COM
because they were slightly simpler to write. But today, almost written as
most
EXE
programs. So in the
entirely with
between
EXE
COM and EXE
rest
all
programs
programs are
of this book, we will be working
al-
programs. Figure 11-4 summarizes the differences programs.
DOSSEG Directive
The
TEST_SEG.EXE, you will notice that the stack memory than the code segment. Yet in the source file you defined the stack (.STACK) before any of the code (.CODE). So why is the stack higher in memory than the code? If
you take
segment
The
is
a look again at
higher in
DOSSEG directive at the start of the program tells the assembler that you
want the segments of your program loaded
in a very specific order with the
code segment appearing
last.
more about
ment
first,
and the stack
In Chapter 14 you will see
DOSSEG and the order of segments when you add another seg-
to hold data.
147
^
Assembly Language
for the
PC, Third Edition
Memory
layout for
.COM
programs
CS, DS, ES,
256 byte PSP
SS
Program, data, and stack
lOOh
SP
Memory
layout for .EXE
programs DS, ES
256 byte PSP
>
CS:IP
Program SS
Data segment Stack area
SP —
-
Figure 11-4:
148
COM vs EXE programs.
11
n
Segments
NEAR and FAR CALLs The
rest
of the information
in this chapter
you won't be making use of read
them
later if
it
is
purely for your interest, since
book. Skip the next two sections and
in this
you find the going tough or you
are anxious to get
back to
programming. Let's step
back for
a
minute and take a
used in previous chapters. Specifically ter 7,
where you
short program
first
let's
learned about the
MOV
DL,41
3985:0102 B90A00
MOV
CX,000A
3985:0105 E8F800
CALL
0200
3985:0108 E2FB
LOOP
0105
3985: 01 0A CD20
INT
20
see
look
CALL
CALL
instructions in
Chap-
You wrote
a very
program
at the short
instruction.
that looked like the following (without the procedure at 200h):
3985:0100 B241
As you can
closer look at the
by looking
at the
machine code on the
tion occupies only three bytes (E8F800).
The
first
left,
byte
CALL instruc(E8h) is the CALL the
The 80x86 calculates the address of the routine you are calling by adding this offset of 00F8h (remember that the 80x86 stores the lower byte of a word in memory before the high instruction
byte, so
(108h
and the second two bytes form an
you have
to reverse the bytes) to the address of the next instruction
in the program). In this case
The fact that this instruction can write a program
NEAR,
NEAR CALLs
like
which
known
is
word for the offset means
64K bytes
Lotus 1-2-3 that
is
long.
larger than
So
that
how is
it
CALLs
that
you
64K? By using FAR,
calls.
are limited to a single segment. In other words, they
the IP register without affecting the
times
you have F8h + 108h = 200h.
uses a single
are limited to a single segment,
rather than
offset.
as intrasegment
CS
register.
change
For this reason they are some-
CALLs.
You can also have FAR CALLs that change both the CS and IP registers. Such CALLs are often known as intersegment CALLs because they call procedures in other segments.
Going along with of the
these
two versions of the
CALL instruction are two versions
RET instruction. The NEAR CALL, as you saw in Chapter 7, pushes a 149
— Assembly Language
single
for the
word onto
PC, Third Edition
the stack for
struction pops this
In the case of
word
its
return address.
The corresponding RET
in-
off the stack and into the IP register.
FAR CALLs
and RETs,
a
word
is
not sufficient because we're
dealing with another segment. In other words, you need to save a two-word return address on the stack: one
other for the code segment (CS).
one
CS
for the
How does
register,
word for the instruction pointer (IP) and the The FAR RET pops two words off" the stack
and the other
the assembler
know which
for IP.
of these two
CALLs and RETs
to use?
When should it use the FAR CALL, and when should it use the NEAR CALL? By putting a NEAR or FAR directive after the PROC directive. By way of example, look at the following program: PROC ONE
PROC
FAR
RET
PROC ONE
ENDP
PROC_TWO
PROC
CALL
NEAR
PROC ONE
RET PROC TWO
ENDP
When
CALL PROC_ONE instruction, it hunts in its PROC_ONE, which, is PROC.ONE PROC FAR. tells whether the procedure is a NEAR or FAR procedure.
the assembler sees the
table for the definition of
This definition In the case of a conversely,
it
NEAR procedure, the assembler generates a NEAR CALL. And
generates a
FAR CALL, as shown in Figure 1-5, if the proceas a FAR procedure. In other words, the as1
dure you're calling was defined
sembler uses the definition of the procedure that you're calling the type of CALL instruction that
For the
RET
150
w determine
needed.
instruction, the assembler looks at the definition of the proce-
dure that contains the tion for
is
RET
PROC_ONE will
instruction. In
be a
FAR RET,
your program, the as
shown
in Figure
RET 1
instruc-
1-6, because
PROC_ONE PROC TWO
is is
declared to be a a
FAR
procedure. Likewise, the
11
[1
RET
in
Segments
NEAR RET. 1
PROC_TWO
PROC NEAR PROC_ONE ^
CALL
FAR CALL
RET
PROC_TWO
ENDP
PROC_ONE
PROC
FAR
RET
PROC_ONE Figure 11-5: The assembler produces a
PROC ONE
FAR CALL.
PROC
Figure 11-6: The assembler produces a
FAR
FAR
HET< PROC ONE
ENDP
ENDP
Return
FAR RET.
What happens when you don't put a NEAR or FAR directive after the PROC? The assembler uses the information in the .MODEL directive to determine
NEAR or FAR if you don't explicitly declare a proceNEAR or FAR. We're using the .MODEL SMALL directive, which
whether procedures are dure
as
tells
the assembler that
are
NEAR
MEDIUM)
you have only one code segment,
procedures. There are other that
tell
explicitly declared as
the assembler to
.MODEL
so
all
the procedures
directives (such as
make procedures FAR
if
they are not
NEAR.
151
2
Assembly Language
for the
PC, Third Edition
More on the INT
Instruction
The INT instruction is much like a CALL instruction, but with a minor difference. The name INT comes from the word interrupt. An interrupt is an external signal that causes the to
80x86
to execute a procedure
what it was doing before it received the
interrupt the 80x86, but
When
80x86
the
it is
interrupt.
and then return
An INT instruction doesn't
treated as if it did.
receives an interrupt,
it
needs to store more information on
the stack than just the
two words
for the return address. It has to store the
values of the status flags
—
flag,
the carry
are stored in the Flag Register,
the zero
flag,
and so on. These values
and the 80x86 pushes
this
information onto
the stack before the return address.
Your IBM
PC regularly responds to a number of different interrupts. The 80x86 IBM PC receives an interrupt from the clock 8.2 times every sec-
inside your
1
ond, for example. Each of these interrupts causes the 80x86 to stop what
doing and execute a procedure to count the clock
pulses.
Now,
it is
envision such
an interrupt occurring between the following two program instructions. CMP
AH,
JNE
N0T_2
Assiune
means
AH = 2, so the zero flag will be set after the CMP instruction, which
that the
Now, imagine tions. it
JNE
instruction will not branch to
that the clock interrupts the
That means the 80x86 runs off^to
80x86 between these two
instruc-
carry out the interrupt procedure before
checks the zero flag (with the JNE instruction). If the 80x86 didn't save and
restore the flag registers, the
JNE instruction would
rupt procedure, not from your the
80x86 always saves and
rupt saves the flags at the
flags,
end
CMP
instruction.
and an IRET
-^
prevent such disasters,
INT 21
inter-
The same
is
true for an
INT
in-
instruction, the 80x86's stack will look
Old IP (return address part
I)
Old OS (return address part II) Old Flag Register
An
{Interrupt Return) instruction restores the
of the interrupt procedure.
like this:
Top Of stack
use flags set by the inter-
To
restores the flag register for interrupts.
struction. After executing the
152
NOT_2.
n
11
The stack grows est in
into lower
memory,
so the
Old
Flag Register
Why save a very
good reason
without
Debug uses the
80x86
trace
the
for saving
this feature.
it
and restoring the
80x86
issues
1
mode known
an
INT
1
after
as single-step
it
at a time.
the stack, issuing an flag.
INT
external interis
no. There
INT instructions.
In
Trap
Flag.
This
mode. Debug
WTien the
flag puts
uses this to
trap flag
is set,
in single-step
mode
executes any instruction.
80x86 won't be
also clears the trap flag so the
while you are inside Debug's
the trap
flags for
surprise.
possible.
a special flag in the flag register called the
into a special
when an
no
is
turns out, the answer
Debug would not be
through programs one instruction
The INT
the interrupt
the flags? Isn't saving the flags useful only
rupt comes at an unpredictable time? As
fact,
actually high-
is
memory.
When you place an INT instruction in a program,
is
Segments
1
procedure. Since
INT
saved the flags to
1
IRET to return to the program you are debugging restores
Then, you
will receive
instruction in your program. This
save the flag registers. But, as
you
is
another just
INT
1
interrupt after the next
one example of when
it is
useful to
will see next, this restore-flag feature isn't
always appropriate.
Some
interrupt procedures bypass the restoration of the flag registers. For ex-
ample, the
INT 21h
procedure in
DOS
by short-circuiting the normal return
sometimes changes the
process.
Many
of the
flag registers
INT 21h
dures that read or write disk information return with the carry flag set
was an error of some
sort (such as
no disk
proceif there
in the drive).
Interrupt Vectors WTiere do these interrupt instructions get the addresses for procedures? Each interrupt instruction has an interrupt number, such as the
The 80x86 tors,
which
21h
in
INT
21h.
finds addresses for interrupt procedures in a table o^ interrupt vecis
located at the
address for the
INT 21h
multiplying the interrupt
bottom of memory. For example, the two-word
procedure
is
number by 4
at
0000:0084. You get
(4 *
21h
this address
= 84h), because
we need
by
four
bytes (two words) for each vector or procedure address.
153
Assembly Language
for the
PC, Third Edition
Vectors are exceedingly useful for adding features to able
you
to intercept calls to interrupt procedures
in the vector table. light to
DOS
because they en-
by changing the addresses
We will use this trick at the end of this book to add a disk
your computer's screen.
and methods should become clearer as you see more examples. Most of this book from here on will be filled with examples, so there will be plenty to study. If you have been feeling a bit overwhelmed by new informa-
All of these ideas
We will
tion, rest easy.
oriented and back
on
take a short breather in the next chapter to get re-
course.
Summary This chapter contained a
lot
of information.
You won't
use
it all,
but you did
need to learn more about segments. Chapter 13 covers modular design, and
you
will use
You began ments.
To
some
aspects of segments to
this chapter
make your job
easier.
by learning how the 80x86 divides memory
understand segments in more
detail,
you
built
with two different segments. You also learned that you need function
ponant
You
4Ch
since
also
rather than
you
will
INT 20h to exit from EXE programs. This is imEXE programs from now on in this book.
be using
found that the lOOh (256-byte) PSP (Program Segment
the start ofyour programs contains a copy of what line.
sets
into seg-
EXE program to use INT 21h,
an
Prefbc) at
you typed on the command
You won't use this knowledge in this book, but it helps you see why DOS aside such a large chunk of memory for the purpose.
Finally
you learned more about the
NEAR, and FAR
directives.
These
DOSSEG, MODEL, .CODE, STACK, are
all
directives that help
you work with
segments. In this book, you will barely use the power of these directives, because our
EXE programs will use only two segments.
But for programmers who
write very ^r^^ programs in assembly language (using the
MEDIUM memory
model), these directives are invaluable. If you are interested, you will find the details in
154
your macro assembler manual.
Segments
11
At the very end of this chapter you learned more about the roots of the helpful
INT
instruction.
to write larger
Now, you
and more
are just about ready to slow
down and
learn
how
useful assembly language programs.
155
— i
I
I
C
I
H A I
I
P
I
T
I
E
I
Course Corrections
How To Bufld Dskpatch In
this
chapter you will learn
more about what is covered in the rest of this at the game plan you will use to build the
book. In particular, you will look
Dskpatch program that Files altered:
None
will
be the center of attention until Part IV.
L
\
m
Topics Covered Disks, Sectors,
The Game Plan
and So Forth
for Building
Summary
Dskpatch
Assembly Language
for the PC, Third Edition
W< have been poking e
into a lot of new
and
interesting places.
wondered whether we have been wandering about somewhat haven't been, of course.
aimlessly.
We
You are now familiar enough with your new surround-
ings for us to plot a course for the rest of this book. at a
You may have
design for the Dskpatch program.
book developing Dskpatch, much
Then you
you
as
We will
will
will later
take a close look
spend the
rest
of
this
develop programs of your
own.
We will not present the finished version of Dskpatch all the
way we wrote
stage of your
want
to go.
it.
we will
Instead,
program
as
you write
at once; that
is
not
present short test programs to check each
it.
To do this, you need to know where you
Hence, our course correction here. Since Dskpatch
will deal
with
information on disks, that's where you will begin.
Disks, Sectors,
and So Forth The information on your floppy disks 512 bytes of information. ted with
is
divided into
sectors.
Each sector holds
A double-sided, double-density 5-1/4" disk format-
DOS 2.0 or above has a total of 720 sectors, or 720 * 512 = 368,640
bytes (see Table 12-1 for other types of disks). If you could look direcdy at these sectors,
you could examine the directory
on the
the
files
use
Debug
disk.
to learn
You cannot more about
— not by sectors
directly, or
you could look
— but Dskpatch
yourself
and
get an idea of
at
will. Let's
how you
will dis-
play a sector with Dskpatch.
Debug
has a
command, L
where you can look starts at sector 5
number tor 5
on
As an example,
from the disk
enter the following: Liee e si
let's
look
memory
at the directory that
a double-sided disk (use Table 12-1 to determine
to use for the directory if you
in drive
Make sure you have a 360K
158
{Load), to read sectors from disk into
at the data.
A (drive (or
what
have a different type of disk). Load secto
Debug) by using the L command.
1.2M, 720K, or 1.44M) disk
in drive A, then
.
12
t
I
Course Corrections
C\
— How To Build Dskpatch
Table 12-1 Starting Sector for the Root Directory Disk Type
Sectors/disk
Directory
5-1/4"
360K
720
5h
5-1/4"
1.2M
2,400
Fh
3-1/2"
720K
1,440
7h
3-1/2"
1.44M
2,880
13h
As you can
see in Figure 12-1, this
command loads sectors into memory, starting
with sector 5 and continuing through one sector
at
an
offset
of 100 within
the data segment.
Address to load segment at
Sector
number
-L 100
5 Disk drive
A Figure 12-1:
To
=
1
Number
of
sectors to read
DEBUG's Load Command.
display sector
5,
you can use a
Dump command as
follows:
D 100
396F 0100
49 42 4D 42 49 4F 20 20-43 4F 4D 27 00 00 00 00
396F 0110
00 00 00 00 00 00 00 60-68 06 02 00 00 12 00 00
396F 0120
49 42 4D 44 4F 53 20 20-43 4F 4D 27 00 00 00 00
396F 0130
00 00 00 00 00 00 00 60-68 06 07 00 00 43 00 00
396F 0140
43 4F 4D 4D 41 4E 44 20-43 4F 4D 20 00 00 00 00
396F 0150
00 00 00 00 00 00 00 60-68 06 18 00 00 45 00 00
396F 0160
41
396F 0170
00 00 00 00 00 00 33 9C-6e 06 00 00 00 00 00 00
53 53 45 4D 42 4C 45-52 20 20 08 00 00 00 00
IBMBIO
COM' 'h.
IBMDOS
.
.
COM' 'h.
.
.
.
.
.
C.
COMMAND COM 'h.
.
ASSEMBLER 3.0.
.
E..
.
.
159
— Assembly Language
PC, Third Edition
for the
•P 396F:0180
46 57 20 20 20 20 20 20-43 4F 4D 20 00 00 00 00
396F:0190
00 00 00 00 00 00 00 00-6F 05 2A 00 80 AF 00 00
396F:01A0
46 57 20 20 20 20 20 20-4F 56 4C 20 00 00 00 00
396F:01B0
00 00 00 00 00 00 00 00-72 05 56 00 81 02 00 00
396F:01C0
46 57 20 20 20 20 20 20-53 57 50 20 00 00 00 00
396F:01D0
00 00 00 00 00 00 98 8A-FF 06 57 00 00 C8 00 00
396F:01E0
43 4F 4E 46 49 47 20 20-44 41 54 20 00 00 00 00
396F:01F0
00 00 00 00 00 00 ID 82-A1 06 89 00 00 28 00 00
We will
use a format
Dskpatch will
will
much
FW
COM
FW
OVL
FW
SWP
CONFIG
DAT
o. *../..
r.V
W..H..
(..
!
Dskpatch, but with improvements.
like this for
be the equivalent of a full-screen editor for disk sectors.
You
be able to display sectors on the screen and move the cursor about the sector
display,
changing numbers or characters
as
you want. You
write this altered sector back to the disk. That actually Dskpatch, because
is
will also
be able to
why it is called Disk Patch
you cannot have more than eight
characters in
the name.
Dskpatch
is
an end in
itself.
you will write.
the motivation for the procedures
It is
by no means
we
In using Dskpatch as an example for this book,
will also
manage to present many procedures to write
your
that you will find useful when you attempt own programs. That means you will find many general-purpose
procedures for display output, display manipulation, keyboard input, and more.
look at some of the improvements you will make to Debug's
Let's take a closer
sector
dump. The display from Debug only shows the "printable"
96 out of the 256 that?
different characters that an
This occurs because
MS-DOS
IBM PC
was designed
characters
can display.
to run
on many
Why is
different
computers, including computers that used simple computer terminals.
author of
chose to show a period for
Debug
puters are PC-compatibles, so there
but no one
restrict its display,
Dskpatch ters
with a
is
for
bit
PC
and
as 7,
which
in Part III
for
compatibles, so you can display
all
characters.
rings the bell.
you
other characters.
will learn
Debug
Most com-
to continue to
Microsoft ever changed the code.
of work. Using the
can display almost
such
at
all
no reason
is
The
DOS
There
256
difi^erent charac-
fiinction 2 for character output,
However,
how
all
You
DOS gives special meaning to some,
are characters for special codes like 7,
to display them.
We will also make heavy use of the fiinction keys so that you can display the next sector by pressing the F4 key.
moving the cursor
160
to that byte
You will
and typing
also be able to
in a
change any byte by
new number.
It will
be just like
n
12
using a
word
processor,
where you can
Course Corrections
easily
— How To Build Dskpatch
change characters. More of these
appear as you slowly build Dskpatch. Figure 12-2 shows what
details will
normal display
will
look
like
—
a vast
its
improvement over the display from
Debug.
88 81 82 83 84 85 86 87 as 89
ee IB
28 38 48 58 68 78
88 98 ne B8 C8 De EB FB
tS3t3C 82 EB 88 88 28 28 C8 8E IB 53 BF BB CD 13 89 BE 16 IE
7C
fiS
IE BB 88 BB BB 81 ft6 75 E8 5F
98 BB 88 28 D8 BF BE 72 28 7C 49 7C 88 E8 8A ee
^
4D 44 4F 48 BB FB 89 88 BB ee 29 28 28 2e 46 BC BB 7C 16 3E 7C B9 BB 18 7C 88 4D 79 33 C8 39 7C ne 18 7C 83 86 BE 7C 7C 89 16 4B 83 C3 48 F7 85 8B 16 52 ftC 88 72 16 8D 7F 28 B9 33 C8 CD 16
Bfl
^
53 2E 38 88 12 88 82 F8 IB 6E 48 41 54 31 32 87 BB 78 ee 88 FC F3 F9 89 47 82 86 13 7C 74 F7 26 16 7C 83 D2 ee 03 7C B8 2e 88 F3 81 86 49 7C 01 58 7C 8B FB B9 BB BB 88 F3 ne 5E IF SF 84
M
8B BC BD BE BF Be BB 42 28 36 86 C7 88 83 58 F7 7C E8 BB 74 8F
812345G789nBCDEF
'02 81 81 ee
88 52 2B C5
88 41 28 37 IF C6 87 3E BB BE 86 IC 7C 89 26 11 83 16 92 88 BE E6 18 BE 44 82
^eHSD0S5.8 OQQ
BB 88 44 59 Ffi
IE
45 7C 13
7C 16
7C 4B 72 7D 9E CD
ai
a
t
e!{|LINK TEST VIDE0_I0;
LINK stitches the procedures of these two files together to create one file containing the entire program. for the resulting
EXE
file,
It
so
uses the
first file
name you
entered as the
name
you now have TEST.EXE.
169
.
Assembly Language
That's
gram
it;
for the
PC, Third Edition
you created one program from two source
identical in function to the
is
from the
single
file
files.
The
final
EXE pro-
COM version you created in Chapter 10
VIDEO_IO.ASM, when it contained the main procedure
TEST_WRITE_DECIMAL.
We will make heavy use of separate source files from here on. Their value will become
clearer as the procedures stack up. In the next chapter,
program
a test
simple
to
dump
test version
you
so will allow
sections of
to save effort.
in hex.
You
you
will write
will usually write a
of a procedure before writing the complete version. Doing
to see
how
and mental turmoil
effort
memory
They
to write a
good
in the process.
are called
final version, as well as to save
There
are several other useful
ways
The Three Laws ofModular Design.
The Three Laws of Modular Design These laws suggestions. if
you
much
in Table 13-1. They aren't really laws, they are we will them throughout this book. Define your own laws But use
are
summarized
like; either
way, stick to the same ones
all
the time.
Your job
will
easier if you are consistent.
Table 13-1 The Three Laws of Modular Design 1
Save and restore
all registers,
unless the procedure returns a value
in that register. 2.
Be consistent about which
registers
you use
For example:
170
DL,
DX
Send byte and word values
AL,
AX
Return byte and word values
BX:AX
Return double-word values
DS:DX
Send and return addresses
to pass information.
be
n
13
Modular Design
CX
Repeat counts and other counts
CF
Set
when
there
is
3.
There
Define
is
all
as
AL
or
Information needed on entry
•
Information returned
•
Procedures called
•
Variables used (read, written, and so on)
modular design
registers,
comment
•
parallel
(registers
An
header:
changed)
in
programming and
electrical engineer, for
example, can build
between modular design
in engineering.
a very
complicated piece of equipment from boxes that perform different func-
tions,
without knowing
ferent voltages
and
how each box works
inside.
different connections, the lack
headache for the engineer
Pieces
AX.
external interactions in the
an obvious
in
an error; an error code
should be returned in one of the such
— Building Programs
But
if
each box uses
dif-
of consistency creates a major
who must somehow provide
a different voltage for
each box and create special connections between boxes. Fortunately for the
number of standard
engineer, there are standards providing for only a small voltages. So, perhaps only four different voltages
need to be provided instead
of a different voltage for each box.
Modular design and standard
interfaces are just as
language programs, and that
why we
is
will lay
and use those laws from here on. As you these rules will
make your
task
much
important in assembly-
down
will see
the laws (so to speak),
by the end of
this
book,
simpler. Let's take a look at these laws
in detail.
Save and restore
/i// registers,
unless the procedure returns a value in that
register.
There
aren't that
many
of a procedure, you careful to restore in
all
free
them
registers in the
them
at the
of the procedures, with
cedure and
POPs
80x86. By saving
registers at the start
for use within that procedure.
end of the procedure. You
PUSH
But you must be
will see us
instructions appearing
first
doing
this
in each pro-
at the end.
171
Assembly Language
The only
PC, Third Edition
for the
exception
is
must return some information
for procedures that
to
the calling procedure. For example, a procedure that reads a character from the keyboard
must somehow return the character. Don't save any registers that
are used to return information.
Short procedures also help the register-shortage problem. At times, you will write a procedure that
is
used by only one other procedure.
help with the shortage of registers,
and
read.
You will
see
more of this
Be consistent about which Your job becomes simpler
data.
For
you
this
You
CX register
The
is
procedure
you use
register for
will also
You will
pair of registers so that
when we
your data can
more about this when we introduce a make use of the DS register.
several times so that
Soon you will write
you can write
a procedure
spaces
1
by calling
Use the
10.
to return
number of characters read from the keyboard (you named READ_STRING).
CX
some
will
do
write a procedure
Finally, set the
Carry Flag (CF) whenever there
ever there isn't an error.
Not
all
is
an
error,
procedures use carry
WRITE_CHAR always works, so there
is
no reason
and so on). In
There
is
this case,
you
no standard here because
and
flags.
clear
it
when-
For example,
to return an error report.
a procedure that writes to the disk can encounter
write-protection, error code.
re-
learn
to
whenever you have a repeat count or when you want
register
But
exchanging information be-
sending information, and one for
need to send addresses for long pieces of
DS:DX
and begin
easier to write
to pass information.
(WRITE_CHAR_N_TIMES) with CX set to
count, such as the this
makes the program
this
write procedures for Dskpatch.
reserved for repeat counts.
one character
to write this
for data
we
registers
will use the
be anywhere in memory.
new segment
also
if standards are set for
tween procedures. Use one ceiving information.
it
as
Not only does
many
errors (no disk,
will use a register to return
DOS
an
uses different registers for
different functions.
Define ^//external interactions in the comment header. There This
is
is
no need
why we
to learn
how a procedure works
place a detailed
header contains
all the
comment header
if all
you want
to
do
is
use
it.
before each procedure. This
information you need to know.
It tells
you what
to
place in each register before calling the procedure, and what information the
172
G
13
Modular Design— Building Programs
procedure returns. Most procedures use
of the procedures use variables
which of these memory variables are read and which are changed. header should
with
list
other procedures called.
much of this
information
is
Pieces
but some
registers for their variables,
memory. The comment header should
in
in
say
Finally, each
An example of a full-blown
header
as follows:
This is an example of a full-blown header. This part would normally be a brief description of what this procedure does.
this procedure will write the message "Sector
For example,
on the first line.
"
On entry:
DS:DX
Address of the message "Sector
Returns:
AX
Error code if there was an error
Calls:
GOTO_XY, WRITE_STRING
(procedures called)
Reads:
STATUS_LINE_NO
(memory variables read only)
Writes:
DUMMY
(memory variables altered)
Whenever you want at this
to use
comment header
any procedure you have written, you can
to learn
how
to use
it.
There
into the inner workings of the procedure to find out
will
just glance
be no need to delve
what
it
does.
You may discover from time to time that your comment headers don't tell you enough
so
When you so
it
you can use the subroutine, and you have
find yourself doing this, consider rewriting your
does a better job of explaining
how
These laws make assembly language programming tain to abide
by them, but often not on the
cedure or program write the program
comment header
the subroutine works. If
you don't
you may find yourself again reading the code.
rewrite the header,
the
to actually read the code.
is
first try.
a test case. Frequently,
we have
The
don't
mind, so on these "rough
in
program without concern
we
easier,
for the laws
and we
first
know
exactly
drafts,"
of modular design.
will
be cer-
version of a pro-
we
how
to
will write
We will just plow
through and get something that works. Then we can backtrack and do a good job by rewriting each procedure to conform to these laws.
Programming is a process
we
will
that goes
show much, but not
all,
by leaps and bounds. Throughout
this
book
of the stuttering that went into writing
173
Assembly Language
for the
Dskpatch. There fore
we
settled
PC, Third Edition
is
room enough to contain all the final version. Our first tries oft:en
not
on the
versions
we wrote
bear very
little
be-
resem-
When you write programs, don't worry
blance to the final versions you will
see.
about getting everything right the
first
time.
Be prepared
to rewrite each pro-
cedure as you learn more about what you really want. In the next chapter, you will build a simple test program to print a block of
memory.
It
satisfied,
and even then, there
The moral
won't be the
is:
A program
final version;
never done
is
we will go through others before we are changes we would like to make.
will be other .
.
.
but
it
must be stopped somewhere.
Using the Programmer's
Workbench The Microsoft MASM 6.0 package includes a fiill programming environment, called the Programmer's Workbench. This can make your job of building assembly language programs
much easier.
In
reality,
some programmers love the
Programmer's Workbench (PWB), and others hate ber of people
we
will
who
continue to use
adventuresome,
it.
Since there are a
num-
PWB, we won't force you to use it in this book; ML and LINK directly. For those of you who feel
don't like
PWB has a lot to offer.
We will use PW^ to build TEST.EXE so you can see how you might use PWB to build your own assembly-language programs that use multiple files. We will assume that you asked to install PWB when you installed MASM 6— if you In this section
we would
like to give
didn't,
go back and do so now.
When
you
first start
PWB
you
you an introduction
will see a screen like the
to using
PWB.
one shown
in Fig-
ure 13-3. At this point you could simply start typing a program, then use the
pull-down menus to save the will take a different approach.
174
^^
file.
But since you already have two
files,
you
n
13
Modular Design
Figure 13-3: Programmer's Workbench when you first start
— Building Programs
in
Pieces
it.
Using PWB's P>ull-Down Menus You
are going to create a
program.
you will boxes.
list,
which
see.
Before
to use them.
To
The keyboard
PWB
you can
we go
pull
down
to use the
that constitute a
menus and
file,
as
dialog
a
interface centers
highlights the
menu, you have two
in the
one menu item. because
all
first letter
of each
you
from the
menu
is
Set
Program List.
menu
.
.
item,
want
will
down,
list,
which
to pull
press the Alt
indicates that
down
the
Make
either use the cursor keys
or type one of the highlighted
pull-down menu. In either
the other
depending on
When you
around the Alt key.
press Ali+ letter. For example,
you see
choices,
keyboard or the mouse.
press Enter to select an item
letters
files
on, a few words about pull-down
menu, by pressing Alt+M. Once the menu and
a hst of
is
PWB makes heavy use of both features, so you will need to know how
whether you want
key,
program
PWB can use this list of files to automatically create the EXE
case,
you will notice
that only
has a letter highlighted. This happens
items are grayed out, which means their options
are not available.
175
.
Assembly Language
PC, Third Edition
for the
Using pull-down menus with the mouse button on the
such
as
menu
menu
is
even
easier.
Simply
click the left
bar at the top of the screen on any of the
Make, and a menu
drop down. You can then
will
click
menu
titles,
on any of the
items to select that item.
Setting the Program List Now
allows
gram and
down
pull
You will
you
list,
the
Make menu and
see the "Select to
open an
Program
Program
existing
item select Program List.
select the
which
List" dialog box, List.
You need
is
a dialog
to create a
.
box that
new
pro-
which you can do by typing a name and pressing Enter. Type TEST
press Enter.
PWB
will display
another dialog box asking
on the
"test.mak." Press Enter or click
new program
list.
if
you want
button
—
to create the file
you do want
Now you will now see the dialog box in
to create a
Figure 13-4.
Run Options Edit Progrart List D :\BOOKSsfiSSEHBLY 3\C0DE .
TEST.fiSM TEST.MftK UIOEO 10. ASH
.
\nSSEMBLy 3\CGDENt .
<
CXI S t Include Depende
CXD <
Enter Esc=Cance
I
is
you have already
Tab=Next Field
176
list.
You want
<
elp
>
Ipseudo
to create
where you actually build program built a
>
gnore Stfsten Include Files
awe List>
Figure 13-4: Use the Edit Program List dialog box
This dialog box
o Top of List
to
add two
and change program
lists,
files
or modify to this
lists.
them once
program
list:
.
.
n
13
Modular Design
— Building Programs
in
Pieces
TEST.ASM and VIDEO.IO.ASM, both of which should be visible in the File List
window two
these
Press
1
near the top of this dialog box.
files
to the
Tab
Program
The
steps
you can follow
to
add
List are as follows:
until the cursor
moves
to the File List
window
(probably
a single Tab).
Use the up and down cursor keys
2.
press the Enter key.
Repeat step 2 to add Press Alt+S or click
4.
program
PWB
TEST.ASM,
TEST.ASM
see
then
in the
Program
window.
List 3.
to highlight
You should now
will
screen that
VlDEO_IO.ASM
on
to the
Program
List.
the button to save this
list.
think for a couple of seconds, then you will see the mostly-blank
you saw when you first started PWB.
It
may not seem like you have
done much, but you have.
TEST.EXE
Building
Make menu again and you will notice it is quite different. Now all the items in this menu are enabled. But you will also notice that test.exe appears in the Build menu item. This means you can build TEST.EXE simply by pulling down the Make menu and selecting Build. What is even better Pull
is
down
that
the
the
PWB keeps track of which files you have changed, and
files
that
it
only assembles
You can
Program
tell
which
List
looking at the Edit
Program List. item in the
.
Make
menu. Ifyou
need to be changed.
is
currently selected by
see
a
name, such as test
If you try building
TEST.EXE, you
will get the following error message:
after this item,
know LINK
:
What
warning L4050: file not suitable for /EXEPACK; relink without
does
EXE file. less
this
mean? By
Packed
disk space.
default,
PWB
tells
the linker to try to pack your
EXE files are files that have been compressed so they take up
The problem
here
is
that your
program
is
so small
it
Program that
List with
name
is
currently selected.
cannot be
size. The file grows because LINK has to EXE file it packs to unpack that program when its
packed without actually growing in
add a small program to any
loaded into memory. Since this unpacker
program, the
is
larger than the entire
you
that the
TEST.EXE
LINK failed.
Ml
;
Assembly Language
for the
PC, Third Edition
What you have to do is change the way PWB tells LINK to create your EXE file. Pull down the Options menu and select link Options Then in the LINK Options dialog box press Alt+R or
up yet another dialog box. this
option
such [
]
is
as [X]).
not checked
You want
to
on
to bring
make
sure
square brackets,
reads the following:
it
Pack EXE file
Finally, click
Tab key select
To
(it is
click
Alt+E or
Press
to
on the
move
button in each of these dialog boxes (or use the
the cursor to the
Build from the
reward you for
all
Make menu.
your hard work, you
the one in Figure 13-5.
You can
button, then press Enter).
Now
should work.
It
will see the final dialog box, like
then elect to run your program.
Opxions
Run
Browse
Build Build operat-ion has been conpleted B Errors/Marnings
un Pro9ran>
<
HBI
Id
ebug Proc|raM>
<
^o^
Definitions File CHUL.DEF]:
i
<
^W)I
^BftTCH /FAR /PftCKC
project target file
Figure 13-5: Final dialog box when
Editing FUes in
PWB finished building your program.
PWB
P^^ could do build programs, would not be that useful. Fortunately, PWB can do much more for you. For starters, you can edit any of the files in If all
your Program
is
List.
ture called Browse,
your program.
178
An easier way to
it
get to your
which enables you
to
jump
files,
ver\'
however,
is
another fea-
quickly to any place in
13
n
Modular Design
— Building Programs
Before you can use the Browse feature, however, you need to enable
down
the Options
menu and
select the
it.
in
Pieces
Pull
"Browse Options..." item. Once the
dialog box appears, press Alt+B to check the "Generate Browse Information"
option (so
it
has [X] next to
selecting Build
it)
and
press Enter. Build
your program again by
from the Make menu. Press Esc when you
see the final dialog
box saying that the Build operation finished. Whenever you rebuild your program with the Generate Browse Information option checked, PWB keeps a lot of information on your program which it needs for all the items in the
Browse menu.
down
menu and select View
You will see a dialog box that lists two files in it. These are the two files that make up your Program List. Select the file TEST.ASM and press Alt+G (Goto). You will now have the file TEST.ASM visible in an edit window (see Figure 13-6) and you can edit TEST.ASM. Pull
the Browse
Relationship.
rch Hake Run Options Browse D :\B00KS\nSSEMBLy.3\C0DE\IEST .asn
DOSSEG .MODEL
SMALL
.STOCK .CODE
EXTRN
HRITE_DEClMfiL:PROC
IESI_WRIIE_DECII«L PROC MOO DX, 12345 CftLL WR I IE_ DECIMAL MOU AH ,4Ch INT 21h TEST WRITE DECIMAL ENDP END
iReturn to DOS
TEST WRITE DECIMAL
CGeneral Help>
Figure 13-6:
Jump
TEST.ASM in
its
own
edit
window.
to Definitions
Move the cursor to the name WRITE_DECIMAL after the CALL. Now pull down the Browse menu and select "Goto Definition." You will see the dialog
179
Assembly Language
box
PC, Third Edition
in Figure 13-7, with
shows
you
for the
all
WRITE_DECIMAL highlighted in the Ust. This Hst
of the procedures,
your program. Press Enter, and
labels, etc. in
WRITE_DECIMAL
are looking at the definition of
now
in the file
VIDEO IO.ASM. Fi le
Edit
Search
Uie u
Hake
Run Goto I ef inition
Tmrl^^H
a Pie [URITE DEC Fi le
N ne s
NON_ZERO STOCK lEST.asB
t
UIDEO_IG.as« (78)
TEST_MRITE_DEClHftL
I
UIDEO_IO.asr HRITE CHAR MRITE DECIMAL MRITE_DIGIT «RITE_DIGIT_LO0P WRITE _HEX WRITE HEX DIGIT
l=Help
Entex-
Esc=Cance
1
easily
using this
menu
subroutine tion...
flu
jump
is
to
item.
>
jump
any definition
You can
in
also find
quickly to any part ofyour program.
any of the all
files
of your project by
of the places where a particular
used in other parts of your program by using the Goto Defini-
item in the Browse menu.
the Browse
you did on your program.
It
your
files
won't
you
since the last time
Changes you make outside
180
to
The information used by
use
elp
Tab=Next Field
Figure 13-7: This dialog box enables you
You can
<
menu comes from
reflect
built
the last build
any changes you have made to
your program from within
PWB.
PWB won't show up inside PWB until you
PWB's Build command
again.
n
13
Loading the Program
Modular Design
— Building Progranns
in
Pieces
List
PWB has one rather rude habit that probably keeps a lot of programmers from When you exit and then start PWB again, remembers all the files using it.
it
you had opened, but using.
You have
You do
this
is
the last
does «
View more...
Comments