Socha, Norton-Assembly Language For The PC-3rd Edition-1992 [PDF]

  • 0 0 0
  • Gefällt Ihnen dieses papier und der download? Sie können Ihre eigene PDF-Datei in wenigen Minuten kostenlos online veröffentlichen! Anmelden
Datei wird geladen, bitte warten...
Zitiervorschau

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






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 .




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>