Copyright 1984 by ABComputing ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ» º Introduction to Assembly Language º º º º by º º º º Bill Salkin º ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ³ Introduction ³ ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ Still looking for the needle in the haystack? Or has it pricked you more than once? These are the sentiments of beginning and experienced assembly language programmers. This column is for beginners and you will get the POINT! We remove the veil of secrecy from the clandestine brotherhood of assembly language programmers, and reveal how easy it is to use assembly language ( Gasp! ). Our approach is to write programs implementing a particular function ( such as clearing the screen ), and examine them. Initially, no explanation of the technical aspects of the program is given. After successfully creating and running several such programs, you will have gained considerable confidence in your assembly language ability. The time is then ripe to "circle back" and explain the omitted technical foundation. Be patient, run all examples, and you will soon find yourself bored with the monotony of the language - but impressed with the power it affords you. ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ³ Assumptions ³ ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ All source code, unless stated otherwise, should run under any release of DOS. You should be familiar with 1) the binary and hexadecimal numbering systems; 2) the terms bits, bytes, and "K." ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ³ Notation ³ ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ The letter "H" is used to indicate a hexadecimal number. Hence 24H = 36 decimal and 0BH = 11 decimal. Binary numbers are terminated with the letter "B". 00000011B = 3 decimal and 00001111B = 15 decimal. Unless we affix an "H" to a number, the number is interpreted as a decimal number. 21 is regarded as 21 decimal, and 21H = 33 decimal. ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ³ Recommended Reading ³ ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ You should purchase the following books: 1) INTRODUCTION to ASM-86, by Intel Corporation, 2) 8088 ASSEMBLER LANGUAGE PROGRAMMING the IBM PC, by David Willen and Jeffrey Krantz. Howard Sams Co. I own both books and will testify to their high tutorial content. Intel's book is not written for the IBM PC explicitly but the information applies to the PC. This book is a beautiful expression of information difficult to find elsewhere. Dan Rollin's book "IBM PC: 8088 MACRO Assembler Programming" should be available soon from Macmillan, and I hope to add it to the above list. Dan is a good writer, and very experienced in assembly language. Scanlon's book will be of use when you can run simple assembly language programs without difficulty. ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ³ ASM. vs. MASM ³ ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ The assembler package as purchased from IBM is called the MACRO ASSEMBLER. Actually, the MACRO ASSEMBLER diskette contains both the assembler ( ASM.EXE ) and a macro assembler (MASM.EXE ). These are distinct processors, with MASM being a superset of ASM. References to "the assembler" in this column apply to both ASM and MASM unless specifically noted. Using ASM, errors detected in source code are displayed and an error code given. For the same program, MASM additionally displays an explanation of the error. (Sometimes these explanations are less clear than no explanation. My favorite is #71 : "This message not currently used." If the space is available, PCFL may want to rent it.) A macro is similar to a subroutine. MASM supports macro processing, and occupies 67K bytes. ASM does not support macro processing, and occupies 52K bytes. ASM can process small programs in a PC with 64K of RAM, but I suggest a minimum of 128K RAM for use with either assembler. Neither assembler currently supports 8087 code. (Rumor: this situation will change soon.) When either assembler prompts for the filespec, if only the filename is keyed, a file extension of ".asm" is assumed. Accordingly, all assembly language source files in this column use ".asm" as the file extension to minimize typing. ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ³ Program Structure ³ ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ In general, an assembly program contains a data segment, stack segment, and a code segment. A segment is a 64K contiguous area used for a specific purpose. The data segment holds data ( constants and variables), and the STACK segment is used as a communications ground for subroutines. The CODE segment contains the "guts" or what we loosely refer to as "the program." Declarations for the DATA, STACK, and CODE segments are shown below. ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ³ DATA SEGMENT ³ ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ DATA SEGMENT PARA DATA ENDS ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ³ STACK SEGMENT ³ ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ STACK SEGMENT PARA STACK 'STACK' STACK ENDS ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ³ CODE SEGMENT ³ ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ CODE SEGMENT PARA CODE ENDS A segment is indicated to the assembler by the statement XXXXXX SEGMENT PARA where XXXXXX is the name of the segment. In a later column we delve into the meaning of PARA, and how the LINKER uses the segment name. A segment is closed or completed, by using XXXXXX ENDS where "XXXXXX" is the name used in the declaration of the SEGMENT ( ENDS = END of Segment ). ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ³ Registers ³ ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ The brain of the IBM PC is the 8088 chip. It contains several registers, of which we mention only four. AX register BX register CX register DX register ÚÄÄÄÄÄÄÄÄÄÄÄ¿ ÚÄÄÄÄÄÄÄÄÄÄÄ¿ ÚÄÄÄÄÄÄÄÄÄÄÄ¿ ÚÄÄÄÄÄÄÄÄÄÄÄ¿ ³ AH ³ AL ³ ³ BH ³ BL ³ ³ CH ³ CL ³ ³ DH ³ DL ³ ÀÄÄÄÄÄÄÄÄÄÄÄÙ ÀÄÄÄÄÄÄÄÄÄÄÄÙ ÀÄÄÄÄÄÄÄÄÄÄÄÙ ÀÄÄÄÄÄÄÄÄÄÄÄÙ Each register can hold a 16 bit ( 2 byte ) number. The largest integer that can be contained in AX,BX,CX, or DX is 65535. Each register is divided into an 8-bit "high" and 8-bit "low" part. As shown above, AH represents the high order 8 bits of the AX register, and AL represents the low 8 bits. The largest integer an 8-bit register can hold is 255. The PC has every kind of register we could want - except a cash register. Certain instructions assume that their input can be found in a given register. For example, the "loop" instruction assumes the CX ( "count" ) register contains the number of iterations; and 2) string related operations assume the SI and DI registers act as "source" and "destination" pointers. Registers are also important because they are the fastest area on the chip that the programmer can access. To store or place the number 8 in the AH register use the assembly instruction: MOV AH,8 The MOV instruction moves the source operand (8) into the destination operand (AH). In assembly instructions, the source operand is always the right operand,and the destination operand is the left operand. The following is an illegal MOV instruction: MOV CL,3000 ;move 3000 decimal into the CL register as an 8-bit register ( CL is an 8-bit register ) can not hold an integer larger than 255. ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ³ Comment (;) ³ ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ A semicolon (;) is used to indicate the beginning of a comment. Any information from the semicolon to the end of the line is disregarded by the assembler. ( Maybe if those darn assemblers would stop ignoring comments and read them, our code would work the way we want it to, not the way we program it! Of course, considering the quality of source code documentation, it may be best to ignore the comments.) Comments can be placed in any column, and used to explain individual source code statements or entire sections. ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ³ Batch File ³ ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ We are almost prepared to run our first assembly language program. But first... the batch file, please. Assembling source code for errors, linking, and running the resultant module is a repetitive process. The batch file 0.bat (contained on this diskette) is simple to use but adequate for our purposes: ASM %1; LINK %1; %1 It will assemble, link and run the program with filespec %1. ASM in 0.bat refers to ASM.EXE, and LINK refers to LINK.EXE ( the "linker" ). Both modules must be available to use 0.bat. To assemble,link, and run the program in file BIGDEAL.ASM, type A>0 BIGDEAL and press the ENTER key. (Recall the assembler defaults to a file extension of ".asm", so the name BIGDEAL used above is regarded as a reference to BIGDEAL.ASM.) Assuming that BIGDEAL.ASM has no errors, the output of the batch file is: A>ASM BIGDEAL; The IBM Personal Computer Assembler Version 1.00 (C)Copyright IBM Corp 1981 Warning Severe Errors Errors 0 0 A>LINK BIGDEAL; IBM Personal Computer Linker Version 2.00 (C)Copyright IBM Corp 1981, 1982, 1983 A>BIGDEAL A> ( NOTE: The linker is version 2.00, as I use DOS 2.0 ). The source code for program BIGDEAL is contained in the file BIGDEAL.ASM on this diskette. Format a new diskette and copy these files to it: ASM.EXE, LINK.EXE, BIGDEAL.ASM, 0.BAT. (Label this diskette "Assembler Work Diskette.") Then apply 0.bat to BIGDEAL.ASM and verify the above output. If the output is not as shown, then YOU SCREWED UP! Continue trying until your output agrees with that shown above. ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ³ Sample Program ³ ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ When BIGDEAL.ASM was assembled,linked, and run, nothing apparent occurred. Try this: type BIGDEAL on the command line and press the ENTER key. The screen looks as follows: A>BIGDEAL A> Still no apparent reaction. Actually, BIGDEAL.ASM contains the linkage conventions needed to return to DOS. (We have gotten "in" and "out" of the program successfully.) This simple program is the foundation on which we build future programs. Study its general structure carefully. Routine BIGDEAL.ASM follows. ;COPYRIGHT 1984 BY ABComputing ; ; ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ; ³ ³ ; ³ THIS ROUTINE RETURNS TO THE CALLER WHEN INVOKED. ³ ; ³ ³ ; ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ ; ;------------------------------------------------------------------------ DATA SEGMENT PARA DATA ENDS ;------------------------------------------------------------------------ ;The above segment is called a data segment. We ;initialize and save variables or constants in this ;segment. Think of a segment as a section of memory ;capable of containing 64K of information. ; ;The above DATA segment does not actually contain any ;data. It is empty. ; ;( NOTE: This small discussion, is a series of comment ;statements as each line is preceded by a semicolon.) ; ;Further note that assembly language code is free format. ;There are no defined positions where instructions or ;directives must be placed. Develop a style of coding ;that appeals to you, and use it consistently. ;------------------------------------------------------------------------ STACK SEGMENT PARA STACK 'STACK' DB 40H DUP('STCK') STACK ENDS ;------------------------------------------------------------------------ ;This is the stack segment. The stack is a common ;communication area for subroutines. Variables are ;"pushed" (saved) onto the stack by one routine to be ;"popped" ( retrieved ) and used by another. ; ;This stack segment is NOT empty. ; ;DB means "define byte." The information following DB is ;regarded as being consecutive bytes in memory. ; ;DUP means "duplicate." The stack contains 40H copies of ;the four bytes 'STCK'. ; ;In summary, as 40H = 64 decimal, the stack segment ;contains 64 copies of the four bytes 'STCK' and occupies ;256 bytes. ; ;If we could look into memory at the STACK segment we ;would see ; ; ... ... ... ... ... ; ; STCKSTCKSTCKSTCKSTCKSTCKSTCKSTCK ; STCKSTCKSTCKSTCKSTCKSTCKSTCKSTCK ; STCKSTCKSTCKSTCKSTCKSTCKSTCKSTCK ; STCKSTCKSTCKSTCKSTCKSTCKSTCKSTCK ; STCKSTCKSTCKSTCKSTCKSTCKSTCKSTCK ; STCKSTCKSTCKSTCKSTCKSTCKSTCKSTCK ; STCKSTCKSTCKSTCKSTCKSTCKSTCKSTCK ; STCKSTCKSTCKSTCKSTCKSTCKSTCKSTCK ; ... ... ... ... ... ; ;Later we show how to view memory using the program ;DEBUG. We won't have difficulty recognizing the STACK ;segment, will we? ;------------------------------------------------------------------------ CODE SEGMENT PARA ;This is the code segment where the "guts" of our program ;goes. ASSUME CS:CODE, DS:DATA, SS:STACK ;The ASSUME statement in the code segment tells the ;assembler to make certain assumptions about the contents ;of certain registers ( Hint: CS = "code segment" and its ;value indicates the start of the code segment; DS points ;to the data segment, and SS points to the STACK segment. ;The assembler is told to assume that these settings are ;in effect.) ; ;It is the programmer's responsibility to adjust the ;contents of these registers ( CS,DS,SS ) to agree with ;the information supplied by the ASSUME statement. ;--STANDARD LINKAGE TO DOS BIGDEAL PROC FAR ;DO PUSH DS ; SUB AX,AX ; PUSH AX ; NOT MOV AX,DATA ; MOV DS,AX ; ALTER! ;We do not explain the standard linkage convention at this ;time, but will later. ;-- RETURN TO DOS RET ;RETurn to DOS ;The RET statement normally RETurns to the program that ;called this program. Through a series of events we return ;to DOS. BIGDEAL ENDP ;END of Procedure CODE ENDS ;END of code Segment ;------------------------------------------------------------------------ END BIGDEAL ;END of routine BIGDEAL ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ³ Conclusion ³ ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ It takes considerable effort to create the simplest assembly language routines. This column has discussed the most difficult aspect of assembly language for the novice - writing your first routine. Future programs are essentially exercises in filling in the data and code segments in the above "shell." Assembly language IS that easy ( almost anti-climactic). And they said you couldn't do it! My next assembly column shows how to clear the display, print a string on the display, and delete a file. These operations invite a discussion of BIOS and DOS calls. The source code for these functions can be viewed by pressing the Esc key, followed by the F2 key. Run each program, and write me if you have any difficulties. P.S. It may be interesting to study the size of an ".EXE" module ( use BIGDEAL.EXE ). Very small, and indicative of the small space used by assembly language modules. ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ³ File Name: ÛÛ asm1.txt ÛÛ ³ ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ  several purposes. It can provide a random subset of a larger p