317 58 84MB
English Pages 477 [493] Year 1985
8088 IBM PC
Assembly Language Programming Gary Shade
Gary A. Shade
CBS Computer Books HOLT,RINEHART AND WINSTON
New York Chicago San Francisco Philadelphia Montreal Toronto London Sydney Tokyo Mexico City Rio dejaneiro Madrid
Gary A. Shade
CBS Computer Books HOLT,RINEHART AND WINSTON
New York Chicago San Francisco Philadelphia Montreal Toronto London Sydney Tokyo Mexico City Rio dejaneiro Madrid
Copyright® 1985 Gary A. Shade All rights reserved. Address correspondence to: 383 Madison Avenue, New York, NY 10017
First distributed to the trade in 1985 by Holt, Rinehart and Winston general book division.
Libr2U*y of Congress Cataloging i||Publication Data Shade, Gary A.
8088/IBM PC Assembly Language Programming
(CBS computer books) Bibliography: p. Includes index.
1.IBM Personal Computer—Programming. 2. Intel 8088 (Microprocessor)—Programming. 3. Assembler language (Computer programming language) I. Title. II. Series. QA76.8.I2594S45 1985 005.2'65 85-14156 ISBN 0-03-001298-8
Printed in the United States of America
Published simultaneously in Canada
CBS COLLEGE PUBLISHING
Holt,^nehart and Winston The Dryden Press Saunders College Publishing
This book is dedicated to my son Jason. May you always communicate with authority and intelligence, and touch those and the world around you with your compassion and understanding. Dad
CP/M is a trademark of Digital Research Incorporated. MS-DOS is a trademark of Microsoft Corporation. Z-80 is a registered trademark of Zilog Corporation. iAPX,INTEL are registered trademarks of Intel Corporation. 6800 and 68000 are registered trademarks of Motorola Inc. WordStar is a registered trademark of MicroPro International. This hook and all programming examples were written using WordStar from MicroPro International.
A special thanks to Intel for their cooperation and in granting reprint permissions for the many illustrations, tables, and data sheets that appear in this hook.
Preface
xi
Chapter Review
Chapter 1
Chapter 2
xiv
Numbering Systems Numbering Systems 2 Character Encoding 11 Chapter 1 Review 13
1
Assembly Language Programming
15
The Programmer 16 Language Differences 17 Computer Languages 18 Assemblers
21
The Editor
23
Symbolic Representation Forward References Cross Assemblers Linkers
23
26
27
27
Creating a Source Program Operand Field 31 Your First AL Program
28
32
The Files You Have Created
38
Chapter 2 Review 40 Chapter 3
8088 Architecture
43
Microprocessors and Microcomputers 43 Bus Architecture(Hardware) 51 PC Memory Map 55 The 8088 Microprocessor 55 Chapter 3 Review 69
Chapter 4
8088 Instruction Set
71
Instruction Groups 72 Data Transfer Instructions
76
Arithmetic Instructions 87 Before You Continue 102
Bit Manipulation Instructions
102
Control and Transfer Instructions
112
String Manipulation Instructions 124 Processor Control Instructions
Chapter 4 Review
130
134 vn
Chapter 5
Assembler Features Assembler Format 136
135
Data Pseudo-ops 136 Symbolic Names 142 More Pseudo-ops 145 Conditional Pseudo-ops 155 Listing Pseudo-ops 158 Operators 162 Chapter 5 Review 168
Chapter6
Macros and MS-DOS Macro Definitions 169
169
MS-DOS/PC-DOS and Macros
Chapter 7
Example Program
185
Chapter 6 Review
188
180
Numbering Conversions: A Programming Example 189 189 Conceptual Design 190 Segment Definitions 192 Program Logic Flow 198 Purpose
Chapter 8
Disk I/O Programming The Diskette
207
209
MS-DOS Programming Tools 213 Methods of File Access
221 Methods of File Access Under MS-DOS 2.0 Absolute Disk Access 229
226
Prograrnming Examples 231
Chapter 8 Review 247 Chapter 9
The Basic Input/Output System
249
Printer I/O 252 Video I/O 253
Graphic Modes 256 Sound
263
Chapter 9 Review
Chapter 10
265
Conununications
267
Methods of Analog Data Transmission 276 A Closer Look at Duplex 278 Asynchronous versus Synchronous Communications 282 Baud Rate
285
Error Checking Modems
285
288
The Program: COMM.ASM
292
MS-DOS RS-232C Functions 302 BIOS Communication Functions 303
A Communications Program: COMM.ASM and DLOAD.ASM
305
In Conclusion
317
Chapter 10 Review
318
Appendix A
321
Appendix B
327
Appendix C
347
Answers to Chapter Reviews
347
Appendix D
353
Bibliography
473
Index
475
This book is intended to be an introduction to Assembly Language programming
on the IBM PC,and to provide the Assembly Language programmer with a valuable reference for future use. Three subject areas are ofinterest when writing programs for the IBM(and compatible computers). These are: 1. the 8088 microprocessor, the brain of the IBM;
2. MS-DOS or PC-DOS,the operating systems for the compatibles and the IBM; and
3. general programming practices, which when applied to Assembly Language programming, make the exercise worthwhile. You should know bow to operate your computer. This book will not instruct you on where the on/off switch is located, nor will it tell you bow to properly insert a
diskette and efficiently use DOS commands, such as DIR or COPY. You should consult your operations manual if these commands do not sound familiar to you.
Why Assembly Language? Assembly Language is capable of creating programs that execute faster and are more efficient in terms of memory usage than are most higher level languages,such as BASIC. Most people have beard about Assembly Language (AL) and Assembly Language Programming (ALP), but few may have already attempted to program their machines using AL.
Assembly Language is intimidating to the novice programmer, but then so are numerous other activities when attempted for the first time.
You'll find that the skills acquired from learning to program your IBM PC will enable you to quickly learn a different microprocessor's architecture and instruc tion set. Once you become really proficient at Assembly Language programming, learning a new microprocessor's architecture and the instructions necessary to program it will take about a month.
The current trend in applications development work is to use higher level lan guages, such as BASIC, FORTH, and Pascal, to reduce programming time. How ever, most applications require some portion of the application program to be written in Assembly Language(AL). xi
High levellanguages such as BASIC and COBOL do speed up development time,but they do not execute as quickly as programs written in AL. Higher level languages also require more memory than programs written in Assembly Language.
Getting to Know Your Micro Perhaps the most important concept any book on Assembly Language Program ming(ALP)must convey is that you,the programmer,will become acquainted with the hardware that makes a computer a computer. This knowledge is essential when writing in Assembly Language. You must know the microprocessor's architecture, its registers and instructions.
As this book is about 8088/IBM ALP programming, you should have access to an IBM PC or one ofthe compatible computers with a minimum of64K memory,two disk drives, PC-DOS or MS-DOS 2.0, the IBM Macro Assembler(IBM part number
60242002), and, optionally, a full screen editor or word processing software package such as WordStarfrom MicroPro Inc. The line editor EDLIN,which comes with PC-DOS,can be used to enter the source examples given in the text; however, a fiill screen editor will make source entry and editing easier and faster.
All the examples in this book were developed under MS-DOS 2.0, a system with 256k of ram,two disk drives, and the Macro Assembler from IBM. The examples themselves are simple enough for first time ALP programmers.Should you want to experiment by using different or more sophisticated programming examples, by my guest. It is the only way you'll become proficient in writing your own pro grams.
ALP A language is nothing more than a form of communication; a vehicle through which ideas, concepts, and actions are expressed. Suppose for a moment that you speak the language known as English, and you are trying to communicate in Spanish. Without knowing the language you can make grandiose gestures, draw pictures, or try some other form of audio/visual maneuvering to convey your meaning.The easiest solution is to find someone who speaks and understands both languages, English and Spanish. If the translation process goes smoothly and correctly, your meaning will be conveyed to the other party. Similarly, when you program in AL, you program in the language ofthe assembler. What you type or enterfrom the keyboard is a language unique to the assembler for a particular microprocessor. The assembier statements are referred to as source xu
code. The hitch is that the computer understands what is known as machine code, which is in the form ofbinary ones and zeros(more on binary in Chapter 1). You are faced with a similar problem; you need a translator.
The assembler translates your source program into a machine readable format that the computer can understand and execute. Should you mistype or misspell an entry, the assembler usually generates an error message. If, however, you enter a valid statement,but the statement is not what you intended,the assembler will not generate an error messsage,and the error may not be found until you try to run the program. The intent is not translated properly; only the process described in your Assembly Language source statement is translated. This translation process is what must occur whenever you program in Assembly Language. The assembler translates your source programs into what is known as executable or object code; the binary ones and zeros the microprocessor under stands.
The Definition of NEW Learning AL does not happen overnight, nor does it occur through osmosis. Whenever you write a NEW AL program, remember that NEW is an abbreviation for Nothing Ever Works the first time. You will most likely find that a few bugs have crept into your program. These errors are common to all programmers and not restricted to just the beginner's code. More often than not your logic will be correct, but you'll have made a syntactical error that the interpreter translated literally when translating your source code. There is one bright note in making mistakes; you learn from them. After spending considerable time poring over a section of code to find an error, you'll find yourself quickly learning and understanding the code in its entirety. While the program examples in this book have been debugged for you(by yours truly), I'm sure that a few typos will creep into your program as you enter the programming examples.
Hardware While it is important to understand the hardware in your PC, I will limit my discussion to the microprocessor(8088)and a few of the support chips found in the PC. 1 will not go into a great amount of detail, as it is not the purpose of this book to delve into hardware specifics about the machine. The section will be more to introduce you to the world where Assembly Language programs must directly deal with such devices and program their operation. The main thrust of this text is to demonstrate how programs are written in the PC-DOS environment. xiii
This implies that the operating system is responsible for initializing the support chips and in carrying out Input and Output(I/O)through these chips. The advan tage inherent in presenting an introduction to ALP in this manner is that the programs you write will be transportable to another MS-DOS or PC-DOS IBM
compatible computer. Should you attempt to directly program these chips, you may find that the physical memory or port address where they reside is not the same in all computers,even though the computers are said to be compatible. Once you feel comfortable programming the PC, you'll be ready to learn more about programming hardware devices such as a communications interface chip (Intel's 8251A), a programmable timer such as the Intel 8253, or a peripheral interface chip such as the Intel 8255.
Chapter 1 is an introductory chapter describing the different numbering systems used in assembler programming. Chapter 2 is an introduction to concepts that apply to all microprocessors and assemblers. Towards the end of the chapter I'll begin to focus directly on the 8088 microprocessor with a programming example that represents your first AL program (if you're new to ALP,of course). Chapter 3 looks at the 8088 architecture in detail. Registers and their usage are defined and programming examples provided. Chapter 4 discusses the instruction set of the 8088 and the manner in which data are accessed(addressing modes). Chapter 5 discusses features ofthe IBM Macro Assembler, MASM.The main empha sis of this chapter is using the many advanced features of the IBM Macro Assembler to control the assembly process. Chapter 6 describes MSDOS and macro instruc tions in detail: What they are and how to use them. A complete macro library is included on the diskette that accompanies this book. The macro library contains macro definitions for all of the functional calls supported by MS-DOS 2.0. Many BIOS macros have also been included.
Chapter 7 demonstrates how a program is written from start to finish. Chapter 8 discusses disk programming. The chapter contains four programming examples, including a program that reads,sorts and displays all filenames found in a diskette's directory.
Chapter9focuses on BIOS,the Basic Input/Output System ofthe PC.Programming examples include graphics and sound routines. Chapter 10 discusses telecom munications and presents an interrupt driven telecommunications program. The XIV
program supports disk and printer spooling while on-line and communcation baud rates up to 9600 baud.
For those of you who are experienced at writing AL programs for the 8088, you
may want to skip directly to Chapters 6 through 10, which provide the necessary information required to write AL programs on the PC. All the information neces
sary to write programs that accept data from the keyboard, disk, and other I/O devices is presented here. There is also information on the operating system, MSDOS,in these chapters.
I hope you find this book instructional and refer to it from time to time as one of your reference books on the IBM PC. Should you wish to communicate with me, you can write me:
do Argonaut Systems POB 2492
Northbrook,IL. 60062
Please include a self-addressed stamped envelope if you expect a reply. You can also leave me electronic mail on CompuServe. My user I.D. number is 71625,121.1 hope to hear from you.
XV
1
It would be nice to have a computer that understood every word(spoken or typed), interpreted its meaning, and understood our numbering system. If that were the
case, programming would be a snap. Nearly anyone couid walk up to the machine, put it into a learning mode, and program it in plain English. If this were the case, there would be no need for this book or others like it. However, these are the
machines of the future, ones that today's science fiction is made from.
Current technology is available that allows machines to talk and to listen to the spoken word. However, these voice input and output devices, like the printer or disk drive attached to your computer, receive and transmit information to and from the computer system via two discrete voltage levels. The voltage is either ON or OFF.
For the time being, computers understand only electrical signals that are either on or off. The language the computer understands is in binary form, the base two numbering system. Therefore, it is imperative that you understand binary and other numbering systems that are commonly used in programming, before you begin to look at Assembly Language programming on the PC. There is not one programming application that I can think of where a basic understanding of the different numbering systems is not important.
I'll examine numbering systems in this chapter and how data are represented using binary and hexadecimal notation. A later chapter provides you with a program that
2 8088!IBMPCAssembly Language Programming
can be run on the PC to convert values among the decimal, binary, and hex adecimal numbering systems.
Binary(Base 2) Humans chose a numbering system for their everyday use that was convenient to
them—decimal, or base 10. As humans have ten digits (10 fingers), we chose a numbering system which also has ten digits—0 through 9. This is convenient for humans, but a microprocessor understands only the presence or absence of an electrical signal.
Since the microprocessor is concerned with only two possible states(ON or OFF), the binary numbering system could be used to represent the two possible states as a binary 1 for the ON condition and binary 0for the OFF state. This is the smallest amount of binary information in a digital system, and it is referred to as a BIT (Binary diglT). Several bits are usually grouped together to convey more information than can be found in a single bit. When8 bits are grouped together,a byte is formed. A word is a grouping ofthe maximum number of bits the microprocessor can store internally. For the 8088, a word consists of 16 bits, the maximum width of any 8088 register(an internal storage location).
Coimting in Binary — Examine for a moment how a decimal number is constructed. The number three-
hundred-and-thirty-five is represented in decimal as 345. There is a one's position, a ten's position, and a hundred's position. Each digit's position is a multiple of the numbering system's base. The first position is 5 x 10 raised to the 0 power. The next digit has the significance of 4 x 10'. The hundred's digit is expressed as 3 x 102. Each successive digit's significance is increased by a factor of ten. Similarly, the binary number 10000111 represents the decimal number 135. The bit positions take on the following significance:
Numbering Systems 3
tSB (Least Significant Bit)
MSB (Most Signifint Bit) b7
bS
bS
b4
b3
b2
bl
bd
1
0
0
0
0
1
1
1
Binary
ISa
64
3£
16
a
4
£
1
Decimal
7
6
2
£
5
£
4
£
3
£
£
£
1
£
0
£
Powers of two
The decimal values for ail bit positions containing a 1 are added together to arrive at the decimal number being represented. A byte of all ones would equal the decimal
value of 255. Since a byte of all zeros is possible, there are 256 total bit combina tions possible within a byte(8 bits). What would the decimal value of the binary number 10101010 be equal to? Figure 1-1 shows the bit significance in a byte. Bit Significance in a Byte BYTE
High Order Nibble Hexadecimal Weight Decimal Weight Binary Weight Bit Position
Byte #1 Byte #2
Low Order Nibble
8
4
2
1
8
4
2
1
64 26
32
8 23
4 22
2
25
16 24
21
1 20
-
128 27
-
B7
B6
B5
B4
B3
B2
Bl
BO
0
1
0
1
0
0
1
0
1
1
1
1
0
0
0
0
—
-
-
Byte # 1 (decimal)
=
Byte #2 (decimal)
=
0 + 64 + 0 + 16 + 0 + C► + 2 + 0 = 82
which equals 52 HEX 128 + 64 + 32 + 16 + 0 + 0 + 0 + 0 == 240
which equals FO HEX Figure 1-1 A total of 256 possible states may be represented In a byte of binary. Sfiown are two bytes of binary. Notice tfiat to represent tfte byte In hexadecimal, the byte Is divided into two 4 bit quantities known as "nibbles".
Table 1-1 shows the binary numbers for 0 through 255 decimal. Notice that each time a bit position that is already set to a binary 1 has one added to it, the digit changes to zero. A carry is generated into the next bit position. This occurs in decimal also. It happens whenever 1 is added to 9: 9
+
1
10,
39
1 = 40,
99 + 1 = 100 etc-
4 80881IBMPCAssembly Language Programming
Table 1-1
8 Bit Binary Examples Binary
Decimal
Hexadecimal
0
00000000
OOH
1
00000001
01H
2
00000010
02H
3
00000011
03H
4
00000100
04H
5
00000101
05H
6
00000110
06H
7
00000111
07H
a
00001000
OSH
9
00001001
09H
10
00001010
OAH
11
00001011
OEM
12
00001100
OCH
13
00001101
ODH
14
00001110
OEM
15
00001111
OFH
16
00010000
10H
250
11111010
FAN
251
11111011
FBH
252
11111100
FCH
253
11111101
FDH
254
11111110
FEH
255
11111111
FFH
Adding numbers in binary is just as straightforward.
Binary b7
Decimal b&
bS
1
1
0
0
0
1
0
1
1
-
b3
bS
bl
b0
1
1
1
1
1
1
0
1
1
£7
1
1
1
0
1
1
+187
0
1
0
1
1
0
£14
b4
-
Carrie
(- = no carry)
Numbering Systems 5
Bit 1(bl)in each of the two values to be added is set to binary 1. When they are added together, they produce binary 0 and generate a carry out of bit 1 into bit 2. But the carry into bit 1 from the previous addition(bO) must also be added. After adding the carry bit to the binary ones occupying the bl position, the result is binary 1, with a carry into the next bit position, b2.
Binary Subtraction To subtract two binary numbers,the concept of two's complement notation must be introduced. In the previous discussion,I spoke only of8-bit unsigned numbers, with a range of0 to 255. I'll now introduce the manner in which signed numbers, positive and negative, are represented. If you're concerned only with unsigned numbers, all eight bits of a byte or all sixteen bits of a word are available to represent a given value. If you want to add -f- 3 to -1,that is to say subtract I from -1-3, the value of -I must be represented within the 8-bit data field. This is accomplished by using the MSB of the data field to represent the sign bit. For byte values, a I in the MSB position indicates that the value of bO through b6 is negative, while a zero in the MSB indicates that the value is positive.
Since the sign bit occupies one bit position,there are only seven bits(fifteen bits for a word)left to hold a binary value. Therefore,the range ofsigned values that can be represented in a byte is: Positive Values
Negative Values
00000000 (decimal 0)
1
1
1
1
1
1
1
1
(decimal -1)
to
01 1
1
1
1
1
1 (decimal +1£:7)
1 0000000 (decimal -128)
It is often convenient to depict positive and negative ranges by using a number line as follows: a-Bit Byte Values 0. -128.....
128. 0. 16-Bit
0..............32,768.
-32,768.....
258
0
+127 Word
Unsigned Binary Signed Binary
Values
65,536
+32,767
Unsigned Binary
Signed Binary
1 can hear you saying,"How the heck does a byte ofbinary one's equal minus one?" Negative numbers are represented in what is known as two's complement nota tion. To perform a two's complement on a binary number,flip all the bit positions and add a binary I. If the bit position was a I, change it to zero. If the bit position
6 80881IBMPC Assembly Language Programming
contained a zero, change it to 1. This forms the one's complement of the binary value. Do this for all the bit positions and add 1 to the result to form the two's complement. Actually, the value to be converted is subtracted from zero to form
the two's complement, but complementing the number and adding 1 also works. The following example illustrates how this is done. Number to converts
0010001 1
One*s Complement:
1 101 1 100
Add a binary 1:
1 101 1 101
(35 decimal)
(-35 decimal)
(Form 2's complement)
To discover what negative number a signed binary field contains, perform a two's complement on the number as follows: Unknown Value:
101 10101
Complement:
01001010
Add a binary 1:
0100101 1
Convert binary to decimal
>>
(-? decimal)
75 decimal (Negative 75) -(64+8+£+i)
By representing negative numbersin two's complement,a subtraction is carried out by adding the two values:(+A)+(-B). Let's say I want to subtract 2from 1.1 would first perform a two's complement on the subtrahend, then add that value to 1. 1) Convert +£ to -2.
Subtrahend:
00000010 (+2)
Complement:
I I I I I I01
Md
1 1 1 1 1 1 10 (-2)
1 :
2) Add -2 to 1. 00000001 (-1-1)
Subtrahend:
'»- l
i
l
l
l l l0 (~2)
1
1
1
1
1
1
1
1 (-1)
Check the answer by performing a two's complement on the result, keeping in mind that when the number is read, it has a negative magnitude.
Numbering Systems 7
Results
l l l l l i l l
Complements
00000000
Add
00000001
I s
(-1)
The value is 1 (negative)
A byte of all I's is equal to a -1, and all subtractions can be carried out through addition.
Converting Decimal to Binary To convert a decimal value to binary, divide the decimal value by 2. Write down
the remainder. If the quotient is zero, you are finished with the conversion. If the quotient is not zero, repeat the process using the quotient as the dividend. For example, convert 137 to binary: step
Quotient
Remainder
1) 137/iE; -
66
1
2) 68/e
=
34
0
3) 34/2
=
17
0
4) 17/2
=
8
1
8/2
=
4
0
6) 4/2
=
2
0
7) 2/2
=
1
0
8) 1/2
=
0
1
Least Significant Bit.
Most Significant Bit
The binary representation of 137 is: MSB