Classic Computer Magazine Archive CREATIVE COMPUTING VOL. 9, NO. 9 / SEPTEMBER 1983 / PAGE 294

Inside the IBM PC - access to advanced features and programming. (book reviews) Susan Glinert-Cole.

Like the other works of Peter Norton (the Norton Utilities, for example), his book on the IBM PC is a superior and classic production. It is possible, for $60, to order a set of three disks which complement the text, but not having them does not lessen the benefit which can be derived from the book.

He assumes a basic knowledge of the IBM PC as well as ome programming experience, so be forewarned: this is not a book for rank beginners. It is aimed at those who are curious enough to go beyond the introductory stages of computing and find out how to get around inside the machine to make it do strange and wonderful things.

The chapters cover the disk operating system (DOS), disk storage, ROM, video and keyboard access with some fascinating asides on Pascal, assembler and warbling. Many of the programs described are written in Pascal (hooray!); it is nice to see some really useful programs written in this language for a change. There is, however, ample coverage of the topics described in Basic as well. In fact, the juxtaposition of the programs makes it easy to compare the style and content of the two languages.

There are also several assembler subroutines with detailed instructions for incorporating them in your main Pascal or Basic program. I highly recommend this book for even the advanced beginner. Most of the topics are easily within the grasp of someone with just rudimentary programming experience, and are so thoroughly and clearly explained that the reader will soon discover that he is suddenly moderately experienced with only a modicum of effort.

Assembly language, or the Art of Programming with a Pair of Tweezers, is always difficult to present in a cozy manner. The problem is that there are so many new concepts to introduce before the issue of programming can be addressed that the reader tends to become overwhelmed by explanations of registers, stacks, and memory segmentation. There is such a myriad of details to be attended to that a good deal of patience (among other attributes) is required to produce a competent assembly language programmer.

Advocates of Assemblers (AA for short) enthusiastically impress upon the unwary the power that assembly language gives a programmer over the machine. Admittedly, it is powerful and allows some elegant and clever manipulations whicha re not possible froma high level langauge and is thus appealing to many people.

Those of you who enjoy or feel impelled to worry a lot will find that assembly language gives you an opportunity to worry about details you never dreamed existed outside of an IRS audit. You will have an opprotunity to chew your fingernails in any base from 2 to 16 by judicious use of the RADIX pseduoop. You can nibble your lip over segmentation and 24 (count 'em) operand addressing modes.

If that still doesn't satisfy you, you can eat your way through a box of orange flavored antacid tablets trying to decide which of the 30 or so jump instructiosn best suits your mood. Assembler is not for amateur worriers.

I confess that, after one semester of IBM 360/370 assembler and 45 boxes of antacid tablets (assorted flavors), the lifestyle simply didn't appeal to me. I grudgingly admit, however, that there are times when assembler is indispensable for getting a job done efficiently. Anyway, if this sounds like something you might enjoy, Leo Scanlon's book will be of use to you.

Parts of this book are likely to be confusing to someone who has never done any assembly language coding before. The examples often clarify what the text leaves obscure, but I think that this book will probably best benefit someone with some prior experience in this area. As with the Norton book, you may order a disk which contains programs mentioned in the text and in this case, I strongly suggest that you do so.

Since this is the first book I have seen which deals in particular with the IBM PC Macro Assembler, it is worth buying just for teh specific information which can be found in it. Like many programming languages, assembler is difficult to learn from a book, and it really requires the IBM Macro Assembler and some hours at the keyborad to become comprehensible.

The book does an excellent job of explaining the 8088 instruction set and higher precision mathematical operations and covers input/output and system resources clearly. The book contains only a few ready-to-type-in programs, but there are quite a few procedures around which a program could be built. One of these subroutines contains the complete data table for "Turkey in the Straw." The complaint I have is with the first chapter, which does an inadequate presentation of the function of an assembler and the very important distinction between assembly time and execution time. I therefore digress for a while to fill in these gaps, for those of you who have raced out to the drugstore in anticipation of an evening with the Macro Assembler. The Macro Assembler

First of all, recall that computer memory is organized into a series of consecutive locations, each of which has its own, unique address. Each location stores one byte of information, which is why a byte is sometimes called the smallest addressable unit.

Bytes of information are accessed by specifying the memory address at which the information resides. In higher level languages, such as Basic, the user may remain unaware and unconcerned about addressing, since lower level computer functions take care of the details involved in assigning symbolic labels, such as variable names, to memory locations. For example, the instruction ANSWER=42 assigns the value 42 to the variable AN-SWER. A memory location is assigned to the label ANSWER and the value 42 is placed there. When the instruction PRINT ANSWER is encountered, the address of ANSWER is looked up in a table and the value at that location is fetched. "Where is it fetched to (from?)," I hear someone saying out there. Aha. The worrying begins.

The central processing unit (CPU) contains certain workspaces, called registers, where many types of data manipulation take place. Again, programmers who use high level languages never need be aware that these things exist, but registers are indispensable in assembly language.

The number of registers, as well as the amount of information they may contain, varies from computer to computer. The IBM 360 has 16 general purpose registers, each of which can contain 32 bits of four bytes. The number of bits that a computer normally handles in a register is called a word; the 360 has a 32-bit word size. Computers may also use double words, which are needed for some types of arithmetic, as well as byte-sized pieces of data.

The IBM PC has a complicated register structure and a debatable word size. There are four 16-bit data registers, but these can also be subdivided and used as eight 8-bit registers. Not even Intel, the designer of the 8088 chip, is sure whether the 8088 has an 8- or a 16-bit word size.

Intelhs iAPX 88 Book, which is a must for 8088 Assembly language programmers, has a section headed "The 8088's Powerful 16-Bit Instruction Set." The first line reads "The 8088 has the most powerful intructions of any 8-bit microprocessor." In fact, the PC is a 16-bit machine inside, but it only communicates 8-bits at a time to the outside world. The compromise "8/16 bit microprocessor" designation is commonly used for the 8088; I think they ought to take the middle course and just call it a 12-bit machine. (Are you beginning to worry about some of these things? You're off to a flying start.)

Arithmetic, to name just one type of instruction, is carried out inside the registers. The Basic instructions ANSWER = 17 + 12 in generalized assembly language appears in Listing 1. MOVE and ADD are examples of mnemonic op codes. The next column contains the operands. In general, the first operand is where the result is left and the second operand contains a value which the op-code manipulates. The first column of the program may contains an optional symbolic label or marker which is used as a location reference for branch instructions.

More about this later.

An assembler is a program, just like the word processor or the Space Potatoes game that you maneuver with such finesse. Its function is to take the program you have written (in what AAs wittily refer to as "meaningful mnemonics") and convert your deathless code into something the computer can understand. In computerese, the assembler takes your sources code and translates it to object code. This translation process is called "assembling."

It is possible (and other necessary) for the programmer to instruct the assembler to do certain things, like reserve space for data and assemble blocks of code only under certain conditions. The instructions the programmer gives to the assembler are called pseudo-op codes, to distinguish them from op-codes, which are instructions to the central processing unit. Pseudo-ops are executed when the assembler is running; op-codes are executed when your object code program is running.

In general, the assembler fetches a line of your source code and translates it to machine code, fetches the next line of your program and translates it, and so on until it finds an END instruction. At this point there lie on your disk two programs: your source code and the object code program which the assembler has so carefully put together. You must then bind in any other pieces of software, such as trigonometric functions and previously assembled code modules, which will be needed by the program.

This process is called linking. A linker may also perform many other necessary functions, not the least of which are to resolve certain address disrepancies and produce an executable piece of software (called a load module). We will leave linkers for an advanced lesson sometime in the future and return to the subject of the moment.

Let us look at a perfectly imaginary assembler at work on an equally mythical assembly program. In Listing 2 are a few lines of meaningful mnemonics.

This programs is written in no particular assembly language (you may have already jumped to that conclusion), but will prove (I hope) instructive nevertheless. The principles described are applicable to any assembler. Listing 3 describes the instruction associated with the mnemonic code, the op code assigned to the mnemonic, the size of the instruction in bytes, and the required operands.

The IBM Macro Assembler is said to be "relocatable" because it generates an object code module which may be placed in any available area of memory when it is loaded. In this case, the actual memory locations are unknown at assembly time. The assembler will assume that the program being at address 00000 and performs all address calculations based on this starting address.

First, the assembler calculates the addresses of all symbolic labels in your program and places them in a symbol table. Second, the machine code isntructions themselves are generated, using the locations computed in the first pass. An assembled source code listing for the above program might look something like Listing 4.

Line 1 generated no object code as it is merely an isntruction to the assembler that this particualr program segment is named HEARTBURN. Line 2 is the first actual program line. The assembler sets a location counter to 00000, and this address is assigned to the first instruction. The assembler consults an op code table and finds that the OP mnemonic has the machine code 14, two operands are needed, and the total length of the instruction is two bytes. The first byte of the assembled instruction is 14, the op code specification.

By consulting another internal table it sees that PEPPERONI is pizza type number 6. This becomes the first nibble of the second byte in the assembled code line. The second operand specifies the number of pizzas required, and the assembler puts this figure into the second nibble of the instruction. The location counter is updated by the length of the instruction (two bytes), and the assembler moves to the next line.

The op code is put into place in the same way; the first nibble of the second byte gets the register specification (A) and the last three nibbles encode the number 42 in hexadecimal. Since this instruction is three bytes long, the next line begins at location 00005.

When the fourth line is assembled, the assembler encodes the location of the storage area PUMPKINS into the last five nibbles. Similarly, in line 7, notice that the location of the symbolic label, TASMANIA, is put into nibbles 3 thru 7.

Lines 13 to 16 are instructions for reserving storage space. The assembler puts aside one word of memory space (two bytes) for PUMPKINS and defines this address to contain the value 542 (21E in hex). A byte of memory containing a value of 12 is assigned to BANANAS, and a byte is reserved for FRIDGE, but nothing is placed there until the program is actually executed. When the instruction END is encountered, the assembler halts.

The programmer now does the linking and loading step. The actual memory locations of the program, and any references to exter M modules which may be used by the program, are reconciled at this time. Having gone to all this trouble to assemble it, let's run through an execution.

Line 2 commands the computer to order two pepperoni pizzas. We will not go into the details of this op code. Line 3 puts the value 42 into the AX register. Line 4 puts the value at PUMPKINS, 542, into the BX register. Line 5 adds the value at BANANAS to whatever is in the AX register, so AX now contains 42 + 12 = 54.

Line 6 compares register BX to AX (dribbling some bits in the process). The second operand (BXe is greater than the first (AX); a flag is set elsewhere in the computer to indicate the result of the comparison. The jump instruction in the next line checks the flag and jumps only if AX is greater than BX. Since it isn't, no jump takes place, and the disk in drive 1 is left unfolded.

In line 8 the contents of the second register are converted to Roman numerals and placed into the AX register for future use. The computer consumes a pizza in line 9 and then executes the programmer in line 10. The last executable instruction on line 11 places the value at BANANAS into the reserved storage at FRIDGE.

Review Grade: A