Você está na página 1de 60

Lab Manual (Computer Engineering, and Software Engineering)

SYSTEM PROGRAMMING
CSC - 395

Department of Computer Science and Engineering BAHRIA UNIVERSITY ISLAMABAD CAMPUS

System Programming Course Code CSC 395


BSE 6 , BCE-6 Assembly Language Manual.

If we hear we forget , if we see we remember , if we do we understand. proverb.

Prepared by:

Rashid Karim Siddiqui

Table of contents
1. Introduction 1.1 Parts of an Assembly Language Program 2. 8086/8088 Assembler Instructions 2.1 The 8088 / 8086 Register set. 3. Labs. 3.1 Lab-1 Debug Introduction. 3.2 Lab-2 Program using in direct and indirect addressing mode using debug. 3.3 Lab-3 Creating Loops. 3.4 Lab-4 More Conditional jumps. Program using MASM To produce .COM program. 3.5 Lab-5 Program using MASM , COM ,writing procedure 3.6 Lab-6 Returning value from procedures. 3.7 Lab-7 Arithmetic using procedures 3.8 Lab-8 key board handling Using DOS int 21 services. 3.9 Lab-9 Color-text graphics. 3.10 Lab-10 Mouse Handling. 3.11 Lab-11 Structures in Assembly Language. 3.12 Lab-12 File Handling. 3.13 Lab-13 Random Access Files. 3.14 Lab-14 DOS, BIOS using Turbo-C 3.15 Lab-15 Create TSR, External Interrupt Handling 3.16 Lab-16 Project Demo. 4.0 Appendix Debug Tutorial.

1.

Introduction

Assembly language is the best computer programming language to understand the working of a computer, its BIOS, and the Operating System. Some people are of the opinion that real programmers write code on bare metal. We salute those who wrote their programs in machine code decades back. In this coursework we use assembler to create COM and EXE files executable at the DOS prompt or through the file manager in Win 3.1 or the Windows Explorer in Win 95/98/98SE/NT/XP/2000.Through assembling process assembly language source code contained in a number of files is converted into executable machine code packaged in a COM file or EXE file . The COM file runs on any x86,and Pentium family of microprocessors and all other compatible microprocessors in DOS and WINDOWS environments. Assembly language is very useful in writing code for any specialized tasks. This manual provides in-depth explanation of the operands required for the assembler instructions. Requirements with respect to setting up the Registers, etc. for an instruction are also pointed out where necessary. Texts within square brackets in the examples are instructions to the programmers using this manual. Sometimes the programmer will have to write some code to complete the example program before he assembles and runs it. Explanation of terms used to enable quick understanding: Read ----a.e. BCD LSB MSB != dword As -------------------------------------After the Execution of the instruction Binary-coded decimal Least Significant Bit Most Significant Bit Is not equal to doubleword

Routines used by the examples in part 5. 8086/8088 Assembler Instructions: ----------------------------------------------------------------------Many of the example programs call some rather small routines.Code for these routines are provided in a file called Irvine16.INC.

Parts of an Assembly Language Program


An 8086/8088 assembly language program is composed of four basic parts: Code part Data declaration part Labels Comments Code part Code part is that part of the assembly language source code file which contains assembly language instruction statements as opposed to data declaration statements. This distinction is just to enable starters to get an overall understanding of what is in an ASM source code input file. Code part consists of assembly language instruction statements. An instruction statement is composed of an optional label, a mnemonic with no operand or one or two operands, and an optional comment. A mnemonic is an easily remembered name for an instruction. (In part "5. 8086/8088 Assembler Instructions", we call every mnemonic an instruction; we hope that serves clear understanding). All the instruction statements together form the code part of an assembly language source code file. An assembly language instruction statement is structured like this: optional label -------label: easily remembered name for an instruction ----------------Mnemonic Mnemonic Mnemonic operands -----------------operand operand1, operand2 optional comment ---------------;no operand ;one operand ;two operands

Labels should have symbolically placeholders,

are otherwise known as symbols. Labels identifying code sections the ":" suffix. Labels identifying data items, labels that EQUate to a value, and labels used in STRUCTure templates as should NOT have the ":" suffix.

Operands tell the processor where to find the data for executing the instruction. Where two operands are required, they must be of the same data type (exception: SHL AX,CL), and must be separated by a comma; the first one is called the destination operand, and the second one is called the source operand. Where two operands are required, the destination holds one data item and after the execution of the instruction it holds the result. (exceptions: (1) both the operands in an XCHG instruction statement hold the other operand's value after the execution of the instruction. (2) OUT 70h,AL. Here, the destination operand cannot hold the result of execution of the instruction). Many a times, where only a single operand is required, that operand is also referred to as the destination operand in the sense that it too holds the result of execution of the instruction (exceptions: MUL CX, IMUL CX, DIV CX, IDIV CX). The destination operand can be a register or memory location; it cannot be an immediate value (exception: OUT 70h,AL. Here, the destination

operand is an immediate value). The source operand can be a register, memory location, or an immediate value. Where only one operand is required, it cannot be an immediate value (exception: JMP 103h). Practically, in the assembly language source code files for MASM, code can mix with data. Because, COM files start executing from the first instruction at offset 100h, this dictates that the first thing at offset 100h should be a JMP instruction which must pass control down to some other location just below the data items. This means that all COM files created using MASM are going to have a JMP instruction at the top (at offset 100h), then some or all of the data after that JMP instruction, then the main code part of the file.

Data declaration part


Data declaration part is that part of the assembly language source code file which contains all the EQUates, and data declaration statements and STRUCTs All the data relevant to the whole program come after the first instruction which is 'JMP MAIN'. That is the most convenient place for data items as all variables declared there can be conveniently referenced in the code below. (See Forward Reference explained below in part "8. Restrictions" for data items declared below all the code). However, data relevant to a callable routine but not used in other parts of the program can be declared right before the callable routine's first instruction to easily identify those variables, constants and EQUates as belonging to that particular callable routine.

Labels
Labels are identifiers of data items (variables, EQUates, and placeholders in STRUCTs) and identifiers of callable routines and code sections. Labels can be composed of letters, digits, and the characters ?, ., @, _, and $. A label must start with a letter and a period can only be used as the first character. Only the first 32 characters of labels are significant by default. MASM provides for the command line option, -L (Label length), to enable the programmer to set the number of characters significant in labels. The number must be within the range 5 to 245. See the MASM program documentation ( MASM.DOC ) for more details.

Code labels must have ":" suffixed to them (e.g. LABEL1: MOV AH,9). Data labels must not have ":" suffixed to them (e.g. DATA1 DB 10h). ":" must be suffixed if the label marks the start of some code in the form of data in which case Control Transfer Instructions referring to it will interpret the label as the constant pointer to the memory location, not its contents. If any instruction other than a Control Transfer Instruction refers to a label with a colon suffix, it will interpret the label as pointing to its contents and not as the constant pointer to the memory location marked by that label.

This is different from other assemblers because we had runtime code

modification in mind. For this reason, please write "OFFSET label_name" like "MOV DX,OFFSET INIT", when dealing with the address of labels whether or not they have the ":" suffix.

Comments
Comments are explanatory text used for program documentation; they are ignored by the assembler. Comments enable other people to understand code. It also helps the programmer himself in future in figuring out what he has written. And they also help in making modifications to and expansion of the program in future. Single line comments start with a semicolon (;) and end with a carriage return. Examples showing single line comments: ;This entire line is a comment. MOV AX,BX ;This comment lies next to an instruction statement. Multi-line comments start with the COMMENT directive. A delimiter character is placed one or more space characters after the COMMENT directive; a second instance of the same delimiter character ends the whole comment. All texts between the identical delimiter characters are ignored together with everything else on the last line of comment. Examples showing multi-line comments: COMMENT 'This comment runs across two lines' COMMENT ^ This comment occupies three lines ^ COMMENT 'This comment ends in this line itself'

Code part and Data declaration part, should they be separate:


There is no strict rule forcing one to keep the code part separate from the data declaration part. Practically, one can do anything; declare data between lines of instruction statements after any RET, IRET, JMP instructions; declare machine code as data between lines of instruction statements; declare machine code as data in the data declaration part (label should have the ":" suffix). The only rule here is that you should not mislead the processor to interpret data as code and execute that, causing the computer to hang. That is, the logical flow of program execution should never see data declarations right where it expects code.

In other words, program execution control should never pass on to the addresses where you have put data declaration statements unless those statements actually contain executable code in the form of data.

2. 8086/8088 Assembler Instructions


Before understanding 8086/8088 assembler instructions, it is proper to have a look at the 8086/8088 Register Set. You can skip this and go straight to subheading "8086/8088 Assembler Instructions" and reach for desired set of assembler instructions under "Classes of Assembler Instructions" if you are in a hurry.

The 8086/8088 Register Set


-----------------------------------The 8086/8088 Register Set consists of H and L group Registers, Pointer and Index Registers, Segment Registers, Instruction Pointer Register, and Processor Status Information Register.

H and L group Registers


----------------------Register Name -------Functional Name ----------16 bits (word) 15 0 --------------------------------------------| AH | AL | --------------------------------------------| BH | BL | --------------------------------------------| CH | CL | --------------------------------------------| DH | DL | --------------------------------------------15 8 7 0 H Group L Group High order 8 bits Low order 8 bits (High order byte) (Low order byte)

AX BX CX DX

Accumulator Base pointer Count Data

The halves of each of these registers can be used separately as 8-bit (byte) storage areas.

Pointer and Index Registers --------------------------Register Name -------Functional Name -----------

SP BP SI DI

16 bits (word) 15 0 --------------------------------------------Stack pointer | SP | --------------------------------------------Stack Base | BP | pointer --------------------------------------------Source | SI | index --------------------------------------------Destination | DI | index ---------------------------------------------

Segment Registers ----------------Register Name -------Functional Name ----------16 bits (word) 15 0 --------------------------------------------Code segment | CS | --------------------------------------------Data segment | DS | --------------------------------------------Extra segment | ES | --------------------------------------------Stack segment | SS | ---------------------------------------------

CS DS ES SS

Instruction Pointer Register ---------------------------Register Name -------Functional Name -----------

IP

Instruction pointer

16 bits (word) 15 0 --------------------------------------------| IP | ---------------------------------------------

Processor Status Information Register ------------------------------------15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 ------------------------------------------------| | | | |OF|DF|IF|TF|SF|ZF| |AF| |PF| |CF| -------------------------------------------------

Flags Register Description: ------------

CF (Carry Flag) - If this flag is set, there has been a carry out or overflow of the MSB of the operand or a borrow to the operand. It is used by instructions that add and subtract multi-byte numbers. PF (Parity Flag) - If this flag is set, the result has even parity, an even number of 1s. AF (Auxiliary Flag) - If this flag is set, there has been a carry out or borrow of the 4 LSBs. This flag is used during decimal arithmetic instructions. ZF (Zero Flag) - If this flag is set, the result of the operation is 0. SF (Sign Flag) - If this flag is set, the result of the operation is a negative number. TF (Trap Flag) - If this flag is set, the processor is put into singleStep mode for debugging. In this mode the processor automatically Generates an internal interrupt (INT 1) after the execution of each instruction, allowing a program to be inspected as it executes instruction by instruction. INT 1 and INT 3 interrupts are used, to show register contents, flags and next instruction, by DEBUG.EXE when you debug a program using the DEBUG commands T and P respectively. IF (Interrupt-enable Flag) - If this flag is set, the processor recognizes external maskable interrupt requests. If this flag is clear, these interrupts are disabled. This flag has no effect on either external nonmaskable or internal (to the processor) interrupts. DF (Direction Flag) - If this flag is set, string operations work in a downwards direction in memory; that is, from high address to low address (right to left). If this flag is clear, string operations work in an upwards direction in memory; that is, from low address to high address (left to right). OF (Overflow Flag) - If this flag is set, an arithmetic overflow has occurred; that is, a significant digit has been lost because the size of the result exceeded the capacity of its destination operand.

10

Lab-1.

Debug Introduction.

Assembly Language Programming using Debug


Objective of this lab is To execute DEBUG commends to assemble, run, and debug Assembly language instructions

The following table lists some common DEBUG commands

Activities: 11. start dos command prompt 2. enter DEBUG command

13. use the R command to examine the contents of all registers


2

34. use the A command to enter the following assembly program


This program is supposed to move (copy) an array A (from offset 200H to 27FH)to array B (from offset 300H to37FH). xxxx:0100 mov SI, 0200 mov DI, 0300 mov [DI], [SI] inc SI inc DI jmp 0100 ; at location 0100 enter move instruction to move 0200 to SI reg ; next instruction is to move 0300 to DI reg ; this instruction is supposed to move data from 0200 to 0300 ; registers are incremented to point to next instruction ; go back to start of program

check to see if the logic of above program is correct.

Start to type in your assembly language program , use A (assemble) command.


XXXX:0100 mov si, 200 XXXX:0103 mov di, 300 XXXX:0106 mov [di], [si] ^ Error XXXX:0106

11

Important point: Note the assembler error appears because we try to move data from a memory location to another memory location. Intel 80x86 instruction set does not allow this addressing mode. We must use a register as a temporary storage. After making the modification, we enter the rest of the program.
5.To list our program, we use the command, u (un-assemble), from starting instruction offset 100H to 10CH. -u 100 10c XXXX:0100 BE0002 MOV SI,0200 XXXX:0103 BF0003 MOV DI,0300 XXXX:0106 8A04 MOV AL,[SI] XXXX:0108 8805 MOV [DI],AL XXXX:010A 46 INC SI XXXX:010B 47 INC DI XXXX:010C EBF2 JMP 0100 6. To examine the register and status flags values, we can use the R, Register, command. -r AX=0000 BX=0000 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000 DS=1172 ES=1172 SS=1172 CS=1172 IP=0100 NV UP EI PL NZ NA PO NC 1172:0100 BE0002 MOV SI,0200 7. To single step through the program, we can use the T, trace, command. In other words, we execute one instruction at a time. -t AX=0000 BX=0000 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0200 DI=0000 DS=1172 ES=1172 SS=1172 CS=1172 IP=0103 NV UP EI PL NZ NA PO NC After the first instruction was executed, the Source Index Register, SI, was changed from 0 to 0200H. 1172:0103 BF0003 MOV DI, 0300 -t AX=0000 BX=0000 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0200 DI=0300 DS=1172 ES=1172 SS=1172 CS=1172 IP=0106 NV UP EI PL NZ NA PO NC After the above instruction was executed, the Destination Index Register, DI, was changed from 0 to 0300H. 1172:0106 8A04 MOV AL,[SI] DS:0200=A3 -t AX=00A3 BX=0000 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0200 DI=0300

DS=1172 ES=1172 SS=1172 CS=1172 IP=0108 NV UP EI PL NZ NA PO NC 12

The memory value at address, DS:0200 was shown to be A3H. After the above instruction was executed, the Register AL was changed from 00 to A3H. 1172:0108 8805 MOV [DI],AL DS:0300=0E -t AX=00A3 BX=0000 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0200 DI=0300 DS=1172 ES=1172 SS=1172 CS=1172 IP=010A NV UP EI PL NZ NA PO NC The memory value at address, DS:0300 was shown to be 0EH. After the above instruction was executed, it was changed from 0E to A3H. 1172:010A 46 INC SI -t AX=00A3 BX=0000 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0201 DI=0300 DS=1172 ES=1172 SS=1172 CS=1172 IP=010B NV UP EI PL NZ NA PO NC After the first instruction was executed, the Source Index Register, SI, was incremented to 0201H. 1172:010B 47 INC DI -t AX=00A3 BX=0000 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0201 DI=0301 DS=1172 ES=1172 SS=1172 CS=1172 IP=010C NV UP EI PL NZ NA PO NC After the above instruction was executed, the Destination Index Register, DI, was incremented to 0301H. 1172:010C EBF2 JMP 0100 After we execute the above JUMP instruction, we will start at the first instruction and get the same results as above again. 8. The above program will be run forever because of the unconditional jump instruction. The above program needs to be modified so the loop runs only 80H times. -u 100 10f 1172:0100 BE0002 MOV SI,0200 1172:0103 BF0003 MOV DI,0300 1172:0106 B98000 MOV CX,0080 ;Initialize loop counter 1172:0109 8A04 MOV AL,[SI] 1172:010B 8805 MOV [DI],AL 1172:010D 46 INC SI 1172:010E 47 INC DI 1172:010F E2F8 LOOP 0109 After single steps through the loop a few times, one can use G command to stop at the instruction after the loop instruction. The processor will stop when the IP reaches 111H. -g 111 AX=0005 BX=0000 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0280 DI=0380 DS=1172 ES=1172 SS=1172 CS=1172 IP=0111 NV UP EI PL NZ AC PO NC

1172:0111 69 DB 69 13

9. We can use the dump command, d, to display memory data of the source array and the destination array. They are identical. -d 200 27f 1172:0200 A3 F5 E0 E9 BD FC 80 3E-E7 04 00 75 03 E9 9A 00 .......>...u.... 1172:0210 BE E7 04 E8 48 02 80 3E-3C 04 00 74 6A 2E A1 BB ....H..><..tj... 1172:0220 E6 BB 22 00 BA 01 00 BF-01 00 CD 21 72 50 8B D8 .."........!rP.. 1172:0230 B8 00 44 CD 21 F6 C2 80-75 68 B8 02 42 B9 FF FF ..D.!...uh..B... 1172:0240 8B D1 CD 21 0E 1F B8 00-3F B9 01 00 BA 9B D7 CD ...!....?....... 1172:0250 21 72 2B 3B C1 75 17 80-3E 9B D7 1A 8E 1E 90 D2 !r+;.u..>....... 1172:0260 75 40 B8 01 42 B9 FF FF-8B D1 CD 21 EB 34 2E 8E u@..B......!.4.. 1172:0270 1E 90 D2 B8 00 42 33 C9-8B D1 CD 21 EB 24 3D 05 .....B3....!.$=. -d 300 37f 1172:0300 A3 F5 E0 E9 BD FC 80 3E-E7 04 00 75 03 E9 9A 00 .......>...u.... 1172:0310 BE E7 04 E8 48 02 80 3E-3C 04 00 74 6A 2E A1 BB ....H..><..tj... 1172:0320 E6 BB 22 00 BA 01 00 BF-01 00 CD 21 72 50 8B D8 .."........!rP.. 1172:0330 B8 00 44 CD 21 F6 C2 80-75 68 B8 02 42 B9 FF FF ..D.!...uh..B... 1172:0340 8B D1 CD 21 0E 1F B8 00-3F B9 01 00 BA 9B D7 CD ...!....?....... 1172:0350 21 72 2B 3B C1 75 17 80-3E 9B D7 1A 8E 1E 90 D2 !r+;.u..>....... 1172:0360 75 40 B8 01 42 B9 FF FF-8B D1 CD 21 EB 34 2E 8E u@..B......!.4.. 1172:0370 1E 90 D2 B8 00 42 33 C9-8B D1 CD 21 EB 24 3D 05 .....B3....!.$=.

10. What does 'loop' do? Change the code using DEC and JNZ so that the program still perform the same.

14

Lab-2 Program using debug in direct and indirect addressing mode.


Purpose of this lab is to give you some practice of use of debug commands and to Introduce direct and indirect addressing modes. You learn the following instructions also: MOV, INC, DEC, ADD Direct addressing mode is used to access data that is located in memory . To access data we must know the Address of the memory location where it is stored. Suppose the data is located at offset 0200 , then we can get the data in a register using one of the following instructions. a) mov AL, [0200] b) mov AX, [0200] the first instruction will move 8 bit (i.e. one byte) of data from data segment from memory location 0200 to AL register. The second instruction will move 16 bit (two bytes) of data from location 0200 and 0201 to 16 bit register AX. The address offset is in the form of a constant number. To access a different location you will give new address . note that the square bracket is part of the direct addressing syntax. If you remove the square brackets from the instruction, 0200 will be treated like a number , rather then an address. Work to be done. : Q1. a.Write a program using Debug that copies 10, 8 bit numbers from one memory area to another. b. Modify the program so that it copies 16 bit numbers. Use direct addressing. Explanation: a. If you look at the statement , you realize that you will be using debug so first of all start debug. Then you see that your program will be copying numbers from memory. That means you will feed 10 numbers into memory using debug command. But first decide the location or offset address to store these numbers, let us suppose you Decide that your numbers will be at 0200 offset. Once you are in debug and you see debug prompt -- you use command a. -- a 0200 This command switches debug into assemble mode.

15

Since the numbers are 8 bit numbers, you will use db directive After feeding 10 numbers , verify using dump command. Then you decide the target area offset, where you will copy these numbers, let us suppose It is 0300. Now you decide where the program instructions are to be stored. Let us suppose it is 0100. Write your program at 0100, then verify using u command , then execute using t command Initially access each number using direct addressing . Then verify the result. b. do part b in the same manner. What is the difference between part a and part b. Your answer: ____________________________________________________________ _______________________________________________________________________ _______________________________________________________________________ Get your answer checker by lab engineer.

Q2. a. Write a program that calculates sum of 10 8 bit numbers and stores it at some memory location. Use direct addressing. b. sum of 10 16 bit numbers. Use direct addressing. Explanation: same as in question 1 above Get your program checked : What is the difference between the two programs: What happens if the sum is larger than FF (hex) in part (a) , or larger than FFFF in part (b). How can you detect this in your program. Your answer :_______________________________________________________________ __________________________________________________________________________ __________________________________________________________________________

16

Indirect Addressing. In the previous problems you have Processed array of 8 bit and array of 16 bit numbers stored in memory at consecutive memory locations using direct addressing. You must have realized that , direct addressing is not very flexible because you have to give address for each data using a separate instruction. Indirect addressing mode is more flexible. In this mode you use a register to hold the address of memory location and use the register in square brackets. For example to access 8 bit data from offset 0200 you do this: Mov BX , 0200 Mov AL, [BX] Or to access 16 bit data Mov AX,[BX} ; assuming BX contains address offset. Q3. Write a program that copies 20 bytes from on memory area to another . First version of this program copies 20 bytes in the same order. but in the second version Contents are Reversed i.e. last byte is copied to first byte , second last byte is copied to second byte and so on. Explanation: do as above but this time use a) direct mode b) indirect mode. Get your programs checked. What is the difference between the two versions. Your answer :_______________________________________________________________ __________________________________________________________________________ __________________________________________________________________________ Q4. Write a program that copies numbers from one area to another but it copies numbers that are Greater than 5. Explanation: do as above but this time how does your program decides which number to Copy and which number to leave. Which instruction is used for this purpose and what Are the details of this instruction. Get your programs checked. Your answer :_______________________________________________________________ __________________________________________________________________________

17

__________________________________________________________________________ Q5. Write a program that copies every 3rd 16 bit number to another area. Explanation: do as above but this time how does your program decides which number to Copy and which number to leave. Which instruction is used for this purpose and what Are the details of this instruction. Get your programs checked. Your answer :_______________________________________________________________ __________________________________________________________________________ __________________________________________________________________________ Q6. Write a program that swaps two 16 bit numbers stored in memory. What is your logic: Your answer :_______________________________________________________________ __________________________________________________________________________ __________________________________________________________________________ Get your programs checked. Code all of the programs using Debug and demonstrate in lab. Marks will be given on demonstration.

18

Lab-3 Creating loops Objective : In this lab we continue our study of addressing modes as well as we explore
loop and other program control instructions. You learn Conditional program control instructions cmp, jnz , jz, je, jne, and How to Watch flags value in debug. From now onward you are required to write down each program logic in pseudo English and draw flow chart where necessary.

Why create loops


In the last lab you observed that using direct addressing you have to provide offset part of data with every move instruction. The register indirect mode made thing better as you provided the offset address only when initializing the register that was used to indirectly access the data. And subsequently you incremented or decremented the register. In later part of the lab you wrote programs that had a lot of similar instruction written repeatedly. You wished there was a way to go back to a previous instruction in the program and execute it again. That is to do repeated steps in a loop.

What type of conditions can be used to create loop.


To set up Loop you need some decision making. You decide whether to go back to a previous instruction or move forward. This decision making is usually done using a pair of instructions. You can create a loop by initializing a register with a number, then you decrement the register at the decision point and if the register is not zero you execute a jump instruction that takes your program to a previous instruction. (fixed number of iterations) Or you can create a loop by initializing the register with zero and then you increment the register with each iteration and at the decision point you compare it with a number and if it is not equal to the value in the register you decide to jump back . (fixed number of iterations) Yet another scheme may be to compare the value of a register with some value and the decide to jump back. (number of iteration depends on how soon the value being tested comes in the register).

19

How to create loop.


The execution of the LOOP instruction involves two steps: 1. Subtract 1 from cx. 2. Compare cx with zero. 3. If cx equals zero, execution continues with the instruction following the loop instruction. Otherwise the program branches back to the destination and the next iteration of the loop takes place. The following code is a simple loop that increments ax 5 times.
mov cx, 5 xxx ; intitalizing cx to 5 ; destination to be used in loop ; here you write instructions ; which you want to execute within the loop dec cx ; subtract 1 from cx, if it is not equal to jnz xxx ;zero jump to doLoop

The xxx is the offset part of instruction where you want to come back in loop if you write your program in debug . The following example illustrates using loops and arrays together.

Example for Loops


The following code sample adds all the integers in an array in memory.
1 2 3 4 5 6 7 8 9 10 11 ; suppose the data to be declared is following 16 bit numbers 100h, 299h, 300h, 400h ; following code is to add them in loop mov si, ____ ; address of the 1st element mov cx, ____ ; initialize loop counter mov ax, 0 ; initialize ax, it will contain the sum xxx add ax, [si] add si, _____; add to si the size of number in bytes dec cx jnz xxx ; note the value of xxx when you feed the ; program

line --1 In debug mode you feed data using db, dw directives and you yourself choose the location for data., Initializes an array of type WORD Line 5: to place the starting offset of intarray in the register si . in debug you note the offset address Line 6:instruction to determine the length of the array i.e. the number of elements in the array. This value is copied to cx so that it can be used to iterate through all the elements. Line 8: The label xxx subsequently used , indicating the beginning of the loop. Line 9: Add the current element of the array (pointed to by si) to ax

20

Line 10: Important: The offset in si has to be incremented by the size of the data type used in the array.Thus si will be incremented by __ to point to the next element in the array. Line 11: As mentioned before, the LOOP instruction will subtract 1 from cx, compare it with zero and then determine whether to loop again or not. If cx is not zero, the program will branch back to the label loopThing. When you execute your program step by step using t command , OBSERVE the Z flag displayed and note when it changes .

Exercise
1. modify the program so that numbers are 8 bit numbers. Create loop using other methods suggested above.(type of conditions to create loops) Get it checked:________________________________________________________ 2. create versions of above programs , in which you use following addressing mode to access numbers.: indirect , indirect with offset , and base index modes. Get it checked :_______________________________________________________ 3. write a program that declares a string of characters in the data section. The program when RUN copies the string to another area in the data section. (How do you declare string of character ?). Get it checked :_______________________________________________________ 4. Write a program that uses a loop to calculate the first ten values in the Fibonacci number sequence {1, 1, 2, 3, 5, 8, 13, }. Initialize an empty array and write these values into the array. Use the instructions given on the next page to learn how to read values stored in memory. In this program you set first to number directly. Ssy for example you decide to store the Fibonacci series starting with offset 0200.

Then you can do this : mov di,0200 Mov [di] ,1 Add di,2 Mov [di],1

; first number ; why add 2 ? __your answer ___________? ; second number

; here you write your logic to calculate and store next numbers in the series. ; you note that every number in the series is the sum of previous two numbers in the series. Get it checked :_______________________________________________________

21

Lab-4 More Conditional jumps. Program using MASM , produce .COM


Objective: In this lab we continue to explore decision making using conditional jumps. We study jump on comparison of unsigned and signed integers. As you know we have learnt to create loops using a counter in cx register. We used jne and je instructions. In this lab we use ja , jnbe, jae , jnb, jb , jnae Code these programs using MASM assembler and produce .COM file. .COM skeleton program skeleton is discussed in Appendix. Test these programs in Debug. Problems to be solved in lab. (use indirect addressing mode) (for unsigned numbers) Q1. suppose you have an array of 16 bit unsigned numbers stored in memory starting with address 0200. you want to copy these numbers to another array in memory at address 0300. Write the program and test it. Draw flow chart of the program , with comments. (on a separate sheet of paper) Get it checked:_________________________________ Q2. Modify the above program so that it copies only those numbers which are greater then 20. Draw flow chart of the program , with comments. Get it checked:_________________________________ Q3. Further modify it so that you copy those numbers which lie between 20 and 50 inclusive. Draw flow chart of the program , with comments. Get it checked:_________________________________ Q4. Write a program that has a string of alpha numeric characters stored at some memory address. You want to copy only small alphabets to some other memory location. Q5. Modify the above program so that you copy Capital letters only. Q6. Modify the above program so that you copy alphabets only Home work: use Base Index , Base Index + offset mode., Use signed numbers.

22

Lab-5 Program using MASM , COM , writing procedure


Objective: In this lab we study how to create procedures , and how to use them. Procedures: Write procedures to do the following. Pass arguments using registers. Q1. suppose you have an array of 16 bit unsigned numbers stored in memory and you want to copy these numbers to another array in memory . Write a procedure and test it in a program . Draw flow chart of the program , with comments. (on a separate sheet of paper) Get it checked:_________________________________ Q2. Modify the above program so that it copies only those numbers which are greater than some given number.. Draw flow chart of the program , with comments. Get it checked:_________________________________ Q3. Further modify it so that you copy those numbers which lie between two numbers inclusive. Draw flow chart of the program , with comments. Get it checked:_________________________________ Returning values from procedures. Q4. Write a procedure that may be used to calculate sum of an array of 16 bit numbers. Pass address and size of array in registers. Receive sum in AX register. Q5. Write a program that has a string of alpha numeric characters stored at some memory address. You want to copy only small alphabets to some other memory location. Write a program that uses a procedure to check whether it is a small letter or capital leter. Q6. Modify the above procedure so that you copy Capital letters only. Q7. Modify the above program so that you copy alphabets only

23

Lab-6 Returning value from procedures.


Objective: We continue to study procedure. In this lab we study various methods of returning values from a procedure. We develop a procedure to do unsigned binary multiplication. We also study DOS interrupt functions to do data Input Output.

Q1. Write a program that has a string of alpha numeric characters stored at some memory address. You want to copy only small alphabets to some other memory area. Write a program that uses a procedure to check whether it is a small letter or capital letter. First version of this procedure returns true / false using a Carry flag. Write and test it. For second version modify it so that the procedure uses Zero Flag to indicate true / false.

Get it Checked :First Version: ________________Second Version_______________ Q2. Write a procedure that accepts two 16 bit unsigned binary numbers in registers (One is Multiplicand and the other is Multiplier). Also you pass offset of the area of memory where you will store the result.. The procedure calculates Product of the two numbers using Shift and Add instructions. Demonstrate the procedure . . Get it Checked :_____________________________ Q3. Write two, first procedure uses DOS INT 21h function to writes a character to the screen. The second procedure uses this procedure to write a string of characters to the screen. The second procedure receives offset of string in DX register and length of string in CX register. Demonstrate these procedures in Lab. Get it Checked : Procedure 1________________ Procedure 2____________________ Q4. Write a procedure that inputs a character from keyboard using DOS interrupt 21h function . Using this procedure , write a program that accepts your name as you type it and stores it in memory. Then using another procedure it converts the string of characters to ALL Capital letters and then Using procedure written in Q3 you write it to screen. Demonstrate All of these Procedures in Lab. Get it Checked :_____________________________

24

Lab-7

Arithmetic using procedures

In this Lab we will create some procedures to do multiplication. You have to think about Their a).Parameter Input requirements and Decide the method of passing parameters. b) Output requirement , i.e. How you get the result. c) you assume that the multiplier , multiplicand and the results are stored in memory. You will write the following versions. 1. Procedure to multiply an 8 bit number(multiplicand) by an 8 bit multiplier. Declare variables to store these in data section of your assembly program. Write down the registers that you are going to use to pass arguments. And the method of parameter passing______________________________ Draw Flow char for the logic at the back of this page, which will be common to all programs. Write the procedure code get it checked _______________________________ Write the call to the procedure get it checked ___________________________ 2. Procedure to multiply an 16 bit number(multiplicand) by an 8 bit multiplier. Declare variables to store these in data section of your assembly program. Write down the registers that you are going to use to pass arguments. And the method of passing parameters.________________________________ (must be different from one used above) Write the procedure code get it checked _______________________________ Write the call to the procedure get it checked ___________________________ 3. Procedure to multiply an 16 bit number(multiplicand) by an 8 bit multiplier. Declare variables to store these in data section of your assembly program. Write down the registers that you are going to use to pass arguments. And the method of passing parameters.________________________________ (must be stack based ) Write the procedure code get it checked _______________________________ Write the call to the procedure get it checked ___________________________ Food for thought: 4. If the multiplicand is 32 bit and you can use only 16 bit registers . What can be done. 5. How can you generalize the procedure , and use a flag to indicate the size of multiplicand so that it adjusts itself.

25

26

Lab-8 keyboard handling Using DOS int 21 services.


Write Procedures for the following. 1. Procedure name readc reads a character from keyboard Receives : Nil Returns : ascii code in AH 2. Procedure Name readalp reads a character from keyboard which must be an alphabet. (waits for an alphabet) (uses readc isalpha , procedure ) Receives : Nil Returns : ascii code of alphabet in AH 3. Procedure Name isalpha checks to see if character is alphabet or not. Receives : Ascii Code in Al register. Returns : Carry Clear if Al register contains ascii code of an alphabet Carry SET if Al register does not contains ascii code of an alphabet Ascii code in Al register. 4. Proceduer Name readalp2 (uses procedure readalp ) Receives : Al register 1 or 2 Returns : Ascii code of an alphabet in Ah register If Al register is 1 it returns Capital Letter If Al register is 2 it returns Small Letter 5. Proceduer Name readStr (read an string of alphabets from keyboard) Receives : in DX offset of an area of memory in data segment In which the string is to be stored. In CX count ( number of character to read) In AL Ascii Code which is used to stop the input process. Returns: string in the buffer. The string is NULL terminated. CX , count of alphabets actually read. ( The procedure continues to read alphabets from keyboard until CX is zero or in the mean while if the user presses a key whose Ascii code was sent in AL register then the procedure stops reading and returns.) 6. Procedure readScan (Read Scan code of key pressed in ah register.

27

Lab-9 Color- text graphics.


=============================================================== Objective: In this Lab we will explore various BIOS, and DOS interrupt services. And Create Useful Procedures around them. You have already used Int 10h, service 0E, int 16 , service 10h and Int 21 Service 1 and created procedures. In this lab you will learn how to define a window in text graphic mode. Write colored text, how to read and set cursor position , how to handle mouse.

Text Graphics Back ground.


When an application program needs to write characters on the screen in text mode, it can choose between three types of video output. MS-DOS level access: using INT 21hOutput is slow and you can not control the text color. BIOS level access: Characters are output using INT 10h functions. These execute more quickly then INT 21h and permit the control of text color. Direct Access: Characters are moved directly to video Ram, so that the execution is instantaneous. Application programs vary in their choice of which level of access to use. Those requiring highest performance choose diret video access. Others choose BIOS level. Those concerned with portability choose DOS , or other Operating System services. Understanding video text. There are two general types of video modes. Text mode and graphics mode. When a computer is booted in MS-DOS the video controller is set to Video Mode 3. which allows Color text , 80 columns by 25 rows. In text mode rows columns are numbered from the top left of the screen , row 0, column 0. and bottom right of the screen is row 25 , column 80. Fonts: characters are generated from a memory resident table of characters fonts. Video text buffers: text mode video memory is divided into multiple separate video pages each with the ability to hold a full screen of text. Attributes: As illustrated below , each screen character is assigned an attribute byte that controls both the color of the character , called the foreground and color of the screen behind the character called background. 28

Each position on the video display holds a single character along with its own attribute (color) the attribute is stored in separate byte., following the character in memory. Blinking: characters on the video display can blink. The video controller does this by reversing the foreground and background colors of a character at a predetermined rate. By default, when a PC boots into MS-DOS mode, blinking is enabled. It is possible to turn blinking off using a video BIOS function. Also, blinking is off by default when you open up an MS-DOS emulation window under MS-WINDOWS. Following BIOS services are used for Text Graphics. To select text graphics mode.
1. INT 10h / Ah=0,AL=3 ; set color text video mode. To Set cursor at specified row, column . 2. INT 10h /ah = 2 ,dh,dl = row , column values,bh = video page Set Cursor position To Get current Cursor shape and position. 3. INT 10h /ah = 3, bh = video page returns CH,CL starting , ending cursor ,lines.DH,DL = row , column . To Scroll a Color Window Up. 4. INT 10h/ah = 6,al=number of lines to scroll ,0 all, bh = video attribute for blanked area, CH,CL, row , column of upper left corner, DH,DL, row , column of lower right corner. To write text with attribute. 5. INT 10h/ ah = 9, al = ASCII code,bh = video page (normally 0),bl = attribute, cx = repetition, count. To write text with default attribute. 6. ah = 0Ah,al = ASCII code, bh = video page, cx = repetition count

29

Work to be done in Lab. 1. Write procedures to do the following: 2. Write String. 3. Initialize video mode. 4. Scroll a window. 5. Set cursor position. 6. Get cursor position. 7. Write text in color . 8. Write color string. Using the above procedures write the following programs. 1. A program that reads keys and prints message informing which Arrow Key is pressed. 2. A program that Scrolls a small window at the centre of screen in blue background With Yellow Text. 3. A program that scrolls a window at the upper-left corner of screen and displays 5 Lines of text with 2 line gap between lines. As Assignment To Be submitted next week. Write a program in text graphics mode that scrolls a blue window at the center of screen And displays following Menu in Yellow color text. 1. 2. 3. 4. 5. Search for telephone number. Enter New Record. Edit Record. Display all. Quit.

Further, the first item must appear as highlighted. If you hit Enter key it gets selected and A message is displayed on a separate window. To select another menu item you use Up arrow Key or down arrow key. As you presses up arrow or down arrow key , the present item is displayed as normal text and next item is displayed Highlighted. The selection moves in a circular fashion.

30

Lab-10 Mouse Handling.


The mouse is usually connected to the computer through an RS-232 serial port. Or PS-2 mouse Port. Before detecting a mouse MS-DOS requires a device driver program to be installed in memory. MS-WINDOWS however has built in mouse driver, but for now we will concentrate on functions provided by MS-DOS. Mouse movements are tracked in a unit of measure called mickeys. One mickey represents approximately 1/200 of an inch of mouse travel. The mickeys to pixel ratio can be set for the mouse, which defaults to 8 mickeys for each horizontal pixel and 16 mickeys for each vertical pixel. Mouse INT 33h Functions. mouse driver interrupts -- INT 33h

INT 33h / AX=0000 - mouse ininialization. any previous mouse pointer is hidden. returns: if successful: AX=0FFFFh and BX=number of mouse buttons. if failed: AX=0 INT 33h / AX=0001 - show mouse pointer. INT 33h / AX=0002 - hide visible mouse pointer. INT 33h / AX=0003 - get mouse position and status of its buttons. returns: if left button is down: BX=1 if right button is down: BX=2 if both buttons are down: BX=3 CX = x DX = y

31

Q1. Write general purpose procedures for mouse handling. Handle Error Condition within the procedures. Q2. Write a Not and Cross Game using Muse handling and Text Graphics.

Lab-11

Structures and macros.

Using structures
Q1. Using a simple structure as shown below declare a variable of this structure, read your name using ReadString Procedure store it in the structure variable. Then print the name on screen taking it from the struct variable. biodata STRUCT name BYTE 000000000000 biodata ENDS Q2. Modify the above structure to include your enrollment number. Get the enrollment Number from keyboard, store it in the structure variable. Print both information.

Q3. Declare an array of biodata structure call it myclass and get names and enrollment number of your class fellows. Store in the array. Save it to a text file.

Q4. Extend question 3 . Get students enrollment number through keyboard and use it to find student name from the array myclass data stored in the file.

Macros.
The term macro procedure is a named block of assembly language statements. Once defined, it can be invoked (called) as many times in a program as one wishes. When a macro procedure is invoked, a copy of its statements is inserted directly into the program. It is customary to refer to calling a macro procedure, although technically there is no CALL instruction involved.

Defining Macros:
32

A macro can be defined anywhere in a programs source code, using the MACRO and ENDM directives. The syntax is: macroname MACRO parameter-1, parameter-2 statement-list ENDM There is no set rule regarding indentation, but the statements between macroname and ENDM must be indented to show that they belong to the macro.

Macro Example:
Lets create a macro named mPutChar that takes a single input parameter called char and displays it on the console by calling WriteChar from the link library we are using: mPutchar MACRO char push eax mov al, char call WriteChar pop eax ENDM Required Parameters Using the REQ qualifier, you can specify that a macro parameter is required. If the macro is called without an argument to match the required parameter, the assembler displays an error. For example: mPutchar MACRO char. REQ push eax mov al,char call Writechar pop eax ENDM If a macro has multiple required parameters, each one must include the REQ qualifier.

Invoking a Macro:
A macro is invoked by inserting its name into a programs source code, possibly followed by macro arguments. The syntax for calling a macro is: Macroname argument-1, argument-2,.

Q1. Write macros for each of the procedures you have written around DOS
33

Interrupt services for keyboard handling and text graphics, and try and submit. Lab-12 File Handling. Objective of this lab is to create General Purpose Procedures to do simple File Handlig.
Function 3Ch - Create or truncate file On entry: AH = 3Ch ,CX = File attribute:0 = normal 1 = read only, 2 = hidden, 3 = system DS:DX = Segment:offset of ASCIIZ file specification On Return: Carry clear if successful: AX = file handle Carry set if unsuccessful: AX = Error code as follows 3: Path not found 4: No handle available (too many files) 5: Access denied Function 3Dh - Open file On Entry: AH = 3Dh AL = access mode, where: 0 = read access 1 = write access 2 = read/write access All other bits off,DS.DX = Segment:offset of ASCIIZ file specification On Return: Carry clear if successful: AX = file handle Carry set if unsuccessful AX = Error code as follows 2: File not found 3: Path does not exist 4: No handle available (too many files) 5: Access denied 0Ch: Access code invalid Function 3Eh - Close file On Entry: AH = 3Eh BX = the file handle On Return: Carry clear if successful, set if failed, when AX = error code 6, invalid handle or not open Function 3Fh - Read file or device On Entry: AH = 3Fh BX = File handle CX = Nurnber of bytes to be read,DS:DX = Segment:offset of buffer area On Return: Carry clear if successful AX = number of bytes read AX = 0 means that EOF was already reached. Carry set if failed, and AX = Error code as follows: 5: Access denied 6: Invalid handle or not open

34

Function 40h - Write to file or device On Entry: AH = 40h BX = File handle CX = Number of bytes to be written DS:DX = Segment:offset of buffer area On Return: Carry clear if successful, when AX = number of bytes written AX = 0 means the disc is full Carry set if failed, when: AX = Error code as follows: 5: Access denied 6: Invalid handle or not open Function 41h - Delete file On Entry: AH = 41h DS.DX = Segment:offset of ASCIIZ file specification On Return: Carry clear if successful, set if failed, when AX = Error code as follows: 2: File not found 5: Access denied =============================================================== Using the above definitions. Do the following. Q1. Write procedures for file handling. i.e. CreateFile, OpenFile, CloseFile, ReadFile, WriteFile, etc. Q2. Using the procedures , write a program that deletes a file, it Prompts for a file name, user types the file name , the name is stored in a buffer then using this name. the program Deletes the file. If no success then prints appropriate message. Q3. Write a program that prepares a backup file, it asks for a file name stores it in a buffer and then creates a backup file and then copies first file into backup file and then closes it. ===============================================================

35

Lab-13 File Handling Random access.


Function 42h- Move file pointer

On entry:
AH = 42h, AL = method code as follows. 0: Absolute byte offset from start of the file. (Always +ve double integer) 1: Byte offset from current location (+ve or -ve double integer) 2: Byte offset from the end of the file (+ve or -ve double integer) BX = File handle CX = MSB of offset , DX = LSB of offset

Returns: Carry clear if successful DX = MSB of new pointer location AX = LSB of new pointer location Carry set if failed, when AX = Error code as follows: 1: function number invalid 6: invalid handle or not open

You have already written File handling procedure in a previous lab. Using those procedures and the function 42h in procedure form. Do the following. Q1. Open an already existing file and read write fixed length text records in it. Then using the file pointer service, position the pointer to desired record. And try read write operations. Q2. You have already written a menu driven program to maintain a telephone Record. Now enhance it to save record in a text file. And retrieve records using random access functions.

Lab-14

Invoke DOS and BIOS Interrupts using Turbo-C.


36

You Can invoke DOD and BIOS services in a C program. There are two options available to you in TURBO-C . a) Using Pseudo variables. Pseudo variable are used without declaration. They behave like normal variables but they do not store data in memory, rather they store data directly into registers. For example _AX stand for register AX , and _AL stand for register AL. Also there are many options available to invoke software interrupts. They are geninterrupt, int86, intdos, int86x, and many more. geninterrupt takes one argument which is the interrupt number to be invoked. Int 86 takes three arguments , first is interrupt number, second and third are address of A REGS type variable which is used to pass values to registers. Example1 : in this example a string is to be written on the screen using DOS int 21h service 9h. char st[80] {String to be printed\n}; writestr() { _AH = 0x9; _DX = (unsigned int) st; geninterrupt(0x21); } b) Using REGS structure. REGS data structure is Defined in DOS.H and is a union. It facilitates accessing full 16 bit registers as well as half registers. Its definition is as follows. Struct full { unsigned int AX; unsigned int BX; unsigned int CX; unsigned int DX; } Struct half { unsigned char Al; unsigned char AH; unsigned char BL; unsigned char BH; unsigned char CL; unsigned char CH; unsigned char DL;

37

unsigned char DH; } Typedef union tagREGS { struct full x; struct half h; }REGS; Example 2. writestr() { REGS regs; regs.h.ah = 0x09; regs..x.dx = (unsigne int) st; int86(0x21,&regs,&regs); } In C there are two functions available to user which can be used to get and set interrupt vector address in the interrupt vector table. This way user can write his own interrupt services. Or modify interrupt services. And install TRS routines to be invoked by internal or external interrupt. 1. Using turbo-C intdos, int86, REGS etc write C functions to do the following. a) read a string of characters. b) write a string of characters. c) read numeric string of characters and convert it to Integer using C library function. d) write a C function that creates color text window. e) write a C function that writes a color text. 2. Using INT 16h , Function 12h you get keyboard flags in ax. The flags status returned by the above procedure is explained below. You can use these if you want to handle special keys. Bit 0 1 2 3 4 5 6 description. if set means Right shift key is down left shift key is down either ctrl key is down either alt key is down scroll lock toggle is on num lock toggle is on caps lock toggle is on

38

7 8 9 10 11 12 13 14 15

insert toggle is on left ctrl key is down left alt key is down right ctrl key is down right alt key is down scroll key is down num lock key is down caps lock key is down sys-reg key is down.

Write a program in C that gets keyboard status word and then prints Message about every key , indicating whether it is set or not.

39

Lab-15. Writing TSR and external interrupt handler. Interrupt Vector Table.
Suppose you write a main program with several subroutines. The way your main program invokes its subroutines is by calling them. If your subroutines are in separately compiled modules , you also need to link together the file containing the program with the files containing the subroutines. The end result is an executable file that contains both the main program and the subroutine. The BIOS and DOS are similar in function to subroutines, but you do not call them by name from your program code. As a result your own program can stay smaller in size because they do not need to take with it the BISO and DOS code. In addition your program never need to know where the BIOS and DOS code is actually located. The way programs initiate BIOS and DOS procedures is with processor interrupts. An interrupt is a signal that tells the microprocessor to stop what it is doing and run a different program. Interrupts can be generated by the microprocessor itself ( for example when a program attempts to divide a number by zero) , by the hardware ( the keyboard, the disk drives, and the clock all generate interrupts), or by software ( your program can issue INT instruction to generate an interrupt). Whenever an interrupt occurs, the processor performs the following steps. 1. The processor saves values of the code segment (CS), instruction pointer (IP), and FLAGS registers on the stack, so it can resume processing where it left off after it handles the interrupt. 2. The processor transfers control to a program whose address is listed in the interrupt vector table, a 256 entry table that starts at location 0 in RAM. This location of this table is fixed by the microprocessor which always assumes that the table is in the same place. 3. Each entry in the interrupt vector table (also called an interrupt vector) is four bytes long and contains a segmented address ( an address in the form of segment: :offset). As with any segmented address, the base is a 16-bit value that identifies a 20-bit address ( the last LSB 4 bits are assumed to be zero) .this points to the start of a segment. The offset identifies the distance from the start of the segment. In each vector table entry , the offset occupies the first two bytes and the segment-part occupies the last two. Because each of the 256 interrupt vectors occupies four the entire vector table is 1k bytes long, ranging from absolute 0 through 3ffh

40

The interrupt vector is chosen when an interrupt occurs depends on the value associated with the interrupt. For example if you issue an INT 21H instruction, the processors will invoke the program whose address is listed in the entry 21h of the interrupt vector table. If an interrupt is associated with an external device, a hardware interrupt comes in on one of the lines connected to an 8259 interrupt controller chip. These lines are automatically mapped to specific entries in the interrupt vector table. A program whose address is listed in the interrupt vector table is known as interrupt handler. When an interrupt handler finishes its processing, it issues an IRET instruction which restores the CS ,IP and FLAGS registers to their previous conditions. Therefore , control returns to exactly where it was when the interrupt occurred. How is the Vector Table initialized. At the instant you turn on your computer, interrupts are turned off. But by turning on your computer you cause your processor to start executing the BIOS code that resides in ROM. One of the first things the BIOS does is to fill in some of the interrupt vectors with addresses of the BIOS routines that serve as interrupt handlers. The BIOS fills in entries for processor interrupts (such as divide by zero), hardware interrupts (such as disk, keyboard, and clock interrupts) and entries for BIOS services. The BIOS sets up some but not all the interrupt vectors. When the BIOS finishes its start up functions it loads DOS or other OS code into memory. One of the first thing DOS does is set up remaining interrupt vectors to point to its own services. The following MAP shows the location of Vector table in RAM.

41

Appendix B gives shows important interrupts. Writing your own Interrupt service routines.
In this section we discuss ways to customize the BIOS and DOS by installing interrupt handlers. As we know, the BIOS and DOS contain interrupt handlers that simplify input/output as well as basic system tasks. For example INT 10h routines may be used for video manipulations, the INT 16h may be used for keyboard handling and so on. An equally important part of the operating system is its set of interrupt handlers that respond to external hardware interrupts. MS-DOS allows you to replace any of these service routines with one of your own. Why would any one want to write his own interrupt handler ?. An interrupt handler might be written for a variety of reasons. You might want your own program to activate when a hot key is pressed, even when the user is running another program. You can also replace one of MS-DOS default interrupt handlers in order to provide more complete services. For example, the divide by zero interrupt activates when the CPU tries to divide a number by zero but there is not standard way to terminate the program, you can replace the handler which prints useful information about your program before it is terminated. You can replace the MS-DOS Ctrl-break handler with one of your own. A user written interrupt service routine can handle hardware interrupts more effectively than MSDOS. For example PCs asynchronous communication handler INT 14h performs no input/output buffering. This means an input character is lost if not copied from the port before next character arrives. A memory resident program can wait for an in coming character to generate a hardware interrupt, input the character from the port store it in a circular buffer. This frees an application program from having to take valuable time away from other tasks to repeatedly check the serial port. How to install your own handler using MS-DOS. INT 21h function 25h and 35h make it possible to install interrupt handlers. Function 35h (get interrupt vector) returns the segment :: offset address of an interrupt vector. Call the function with the desired interrupt number in AL. the 32-bit vector is returned by MSDOS in ES:BX. The following statements would retrieve the INT 9 vector , for example.

42

.data Int9sav LABEL WORD DWORD ? .code mov ah,35h mov al,9 int 21h mov intsave,bx mov intsave+2 , es int 21h function 25h (set interrupt vector) lets you replace an existing interrupt handler with a new handler. Call it with the interrupt number in AL and the segment-offset address of your own interrupt handler in DS:DX, FOR example. Mov ax, SEG kybd_rtn Mov ds,ax Mov dx,offset kybd_rtn Mov ah,25h Mov al,9h Int 21h Ctrl-break Handler example. If Ctrl-Break is pressed by the user when an MS-DOS program is waiting for input, control passes to the default INT 23h interrupt handler procedure. The default Ctrl-Break handler terminates the currently running program. This can leave the current program in an unstable state since files might be left open, memory not released, and so on. It is however possible to substitute your own code into the INT 23h handler and prevent program from halting. The following program installs a simple Ctrl-Break handler. .code Org 0100 Entry jmp main breakMsg BYTE BREAK,0 msg BYTE Ctrl-Break demonstration. BYTE 0dh,0ah BYTE This program disables Ctrl_Break (Ctrl-C), press any key BYTE 0dh,0ah BYTE to continue or press ESC to end the program, odh,0ah Main proc Mov dx,offset msg Call writeString

43

Install_handler: Mov ah,25h Mov al,23h Mov dx,offset break_handler Int 21h L1: mov ah,1 Int 21h Cmp al,1Bh Jnz L1 Int 20h Main endp Break_handler proc Push ax Push dx Mov dx,offset breakMsg Call WriteString Pop ax Pop dx IRET Break_handler endp END entry

How to install Interrupt Services using C code. Turbo-C provides very useful data structures and functions to handle system level programs. To read/write a interrupt vector table entry it defines getvector() and setvector() functions. In C language you can declare pointer to functions like this. Void (* funcptr)(); And a pointer to interrupt handler may be defined like this Void interrupt (*inthandler)();

44

The following code shows some sample programming to install interrupt handler and invoke it. We will be using int 65h , this interrupt is not being used by DOS, so we can use it without fear void interrupt *oldint65(); char st[80]={Hello$}; void interrupt newint65(void); void main() { oldint65 = getvect(0x65); // get old int 65 vector setvect(0x65,newint65); geninterrupt(0x65); // invoking interrupt 65h geninterrupt(0x65); setvect(0x65,oldint65); // restore old interrupt } // this is the code that is executed as interrupt handler 65h void interrupt newint65() { _AH = 0x09; _DX = (unsigned int) st; geninterrupt(0x21); } HOW INSTALL A TSR. The following is a sample program that is installing a TSR It is very similar to the above code except that it uses function keep. Keep function reserves requested amount of space and the part of program that acts as interrupt handler is kept in memory even if the installer program exits.

45

#include<BIOS.H> #include<DOS.H> char st[80] = {"TSR Run example\n$"}; void interrupt *oldint65; void interrupt newint65(); void main() { oldint65 = getvect(0x65); setvect(0x65,newint65); keep(0,1000); } void interrupt newint65() { _AH = 0x09; _DX = (unsigned int) st; geninterrupt(0x21); } Project: Write a TSR program that acts like a screen saver running under DOS.

Lab-16

Project Demo.

Each Student shell give a 10 minutes presentation on the given topic and demonstrate code in the Lab.

46

APPENDIX A

Debug Commands Tutorial

DEBUG This tutorial is made to present an overview of the DEBUG.COM program for the IBM PC. This utility can be extremely useful, when used correctly. It is almost a must for Assembler Language programmers, and can also provide an insight into the operation of the machine at the bit level. It has several nice features, including the ability to display and change any of the registers in the IBMPC, start and stop program execution at any time, change the program, and look at diskettes, sector by sector. DEBUG works at the machine code level, but it does also have the ability to disassemble machine code, and (at dos 2.0), assemble instructions directly into machine code.

STARTING DEBUG There are two ways to start DEBUG with a file. Both ways produce the same results, and either can be used. Suppose you want to debug myprog.com. In the Command Line: A>debug myprog.com A>debug -n myprog.com -l

Separate from the command line:

With either method, you will get the DEBUG prompt of a hyphen (-). DEBUG has loaded your program and is ready to run. The description of each instruction will assume this as a starting point, unless otherwise mentioned. If at any time you get different results, check your procedure carefully. If it is correct, please leave me a message. I have tried to check everything, but I have been known to make a mistake or two (anyway). If you do have problems, you can enter the command Q (Quit) any time have the DEBUG prompt (-). This should return you to the DOS prompt. RUNNING DEBUG DISPLAY COMMANDS Register command The first thing we should look at are the registers, using the R command. If you type in an R with no parameters, the registers should be displayed as so: you

47

AX=0000 BX=0000 DS=6897 ES=6897 6897:0100 E96B01

CX=0446 DX=0000 SP=FFFE SS=6897 CS=6897 IP=0100 JMP 026E

BP=0000 SI=0000 DI=0000 NV UP DI PL NZ NA PE NC

CX contains the length of the file (0446h or 1094d). If the file were larger than 64K, BX would contain the high order of the size. This is very important to remember when using the Write command, as this is the size of the file to be written. Remember, once the file is in memory, DEBUG has no idea how large the file is, or if you may have added to it. The amount of data to be written will be taken from the BX and CX registers. name. If we want to change one of the registers, we enter R and Let's place 1234 (hexadecimal) in the AX register: R and AX register Debug responds with register and contents : is the prompt for entering new contents. Debug is waiting for the next command. the register

-R AX AX 0000 : 1234 -

We respond 1234

Now if we display the registers, we see the following: AX=1234 BX=0000 DS=6897 ES=6897 6897:0100 E96B01 CX=0446 DX=0000 SP=FFFE SS=6897 CS=6897 IP=0100 JMP 026E BP=0000 SI=0000 DI=0000 NV UP DI PL NZ NA PE NC

Note that nothing has changed, with the exception of the AX register. The new value has been placed in it, as we requested. One note. The Register command can only be used for 16 bit registers (AX, BX, etc.). It cannot change the 8 bit registers (AH, AL, BH, etc.). To change just AH, for instance, you must enter the data in the AX register, with your new AH and the old AL values. Dump command One of the other main features of DEBUG is the ability to display areas of storage. Unless you are real good at reading 8088 machine language, the Dump command is mostly used to display data (text, flags, etc.). To display code, the Unassemble command below is a better choice. If we enter the Dump command at this time, DEBUG will default to the start of the program. It uses the DS register as it's default, and, since this is a .COM file, begins at DS:0100. It will by default display 80h (128d) bytes of data, or the length you specify. The next execution of the Dump command will display the following 80h bytes, and so on. For example, the first execution of D will display DS:0100 for 80h bytes, the next one DS:0180 for 80h bytes, etc. Of course, absolute segment and segment register overrides can be used, but only hex numbers can be used for the offset. That is, D DS:BX is invalid. With our program loaded, if we enter the Dump command, we will see this: 6897:0100 6897:0110 6897:0120 6897:0130 6897:0140 6897:0150 6897:0160 E9 72 72 62 77 00 00 6B 69 72 6C 61 00 00 01 67 79 69 72 00 00 43 68 20 63 65 00 00 4C 74 44 20 00 00 00 4F 20 2E 64 00 00 00 43 28 20 6F 00 00 00 4B-2E 43-29 53-74 6D-61 00-00 00-00 00-00 41 20 75 69 00 24 00 53 31 63 6E 00 00 00 4D 39 6B 20 00 00 00 43 38 6C 73 00 00 00 6F 33 65 6F 00 00 00 70 4A 50 66 00 00 00 79 65 75 74 00 00 00 ik.CLOCK.ASMCopy right (C) 1983Je rry D. StucklePu blic domain soft ware............ .........$...... ................

48

6897:0170

00 00 00 00 00 00 00 00-00 00 00 00 44 4F 53 20

............DOS

Notice that the output from the Dump command is divided into three parts. On the left, we have the address of the first byte on the line. This is in the format Segment:Offset. Next comes the hex data at that location. Debug will always start the second line at a 16 byte boundary; that is, if you entered D 109, you would get 7 bytes of information on the first line (109-10F), and the second line would start at 110. The last line of data would have the remaining 9 bytes of data, so 80h bytes are still displayed. The third area is the ASCII representation of the data. Only the standard ASCII character set is displayed. Special characters for the IBMPC are not displayed; rather periods (.) are shown in their place. This makes searching for plain text much easier to do. Dump can be used to display up to 64K bytes of data, with one restriction: It cannot cross a segment boundary. That is, D 0100 l f000 is valid (display DS:0100 to DS:F0FF), but D 9000 l 8000 is not (8000h +9000h = 11000h and crosses a segment boundary). Since 64K is 10000h and cannot fit into four hex characters, Dump uses 0000 to indicate 64K. To display a complete segment, enter D 0 l 0. This will display the total 64K segment. If, at any time you want to suspend the display of data, Cntl-NumLock works as usual. If you want to terminate the display, Cntl-Break will stop it and return you to the DEBUG prompt.

Search Search is used to find the occurrence of a specific byte or series of bytes within a segment. The address parameters are the same as for the Dump command, so we will not duplicate them here. However, we also need the data to be searched for. This data can be entered as either hexadecimal or character data. Hexadecimal data is entered as bytes, with a space or a comma as the separator. Character data is enclosed by single or double quotes. Hex and character data can be mixed in the same request, i.e. S 0 l 100 12 34 'abc' 56 is valid, and requests a search from DS:0000 through DS:00FF for the sequence of 12h 34h a b c 56h, in that order. Upper case characters are different than lower case characters, and a match will not be found if the case does not match. For instance, 'ABC' is not the same as 'abc' or 'Abc' or any other combination of upper and lower case characters. However, 'ABC' is identical to "ABC", since the single and double quotes are separators only. An example is looking for the string 'Sat'. Here's what would happen:

-S 0 l 0 'Sat' 6897:0235 Again, the actual segment would be different in your system, but the offset should be the same. If we then displayed the data, we would find the string 'Saturday' at this location. We could also search on 'turda', or any other combination of characters in the string. If we wanted to find every place we

49

did an Int 21h (machine code for Int is CD), we would do the following: -S 0 l 0 cd 21 6897:0050 6897:0274 6897:027F 6897:028B 6897:02AD 6897:02B4 6897:0332 6897:0345 6897:034C 6897:043A 6897:0467 6897:047A 6897:0513 6897:0526 6897:0537 6897:0544 DEBUG found the hex data CD 21 at the above locations. This does not mean that all these addresses are INT 21's, only that that data was there. It could (and most likely is) an instruction, but it could also be an address, the last part of a JMP instruction, etc. You will have to manually inspect the code at that area to make sure it is an INT 21. (You don't expect the machine to do everything, do you?). Compare command Along the same lines of Dump and Search commands, we have the Compare command. Compare will take two blocks of memory and compare them, byte for byte. If the two addresses do not contain the same information, both addresses are displayed, with their respective data bytes. As an example, we will compare DS:0100 with DS:0200 for a length of 8. -d 0100 l 8 0200 6897:0100 E9 65 6897:0101 6B 70 6897:0102 01 74 6897:0103 43 65 6897:0104 4C 6D 6897:0105 4F 62 6897:0106 43 65 6897:0107 4B 72 6897:0200 6897:0201 6897:0202 6897:0203 6897:0204 6897:0205 6897:0206 6897:0207

None of the eight bytes compared, so we got output for each byte. If we had gotten a match on any of the bytes, DEBUG would have skipped that byte. if all of the locations requested matched, DEBUG would have simply responded with another prompt. No other message is displayed. This is useful for comparing two blocks of data from a file, or a program with the BIOS ROM. Otherwise, I have not found a great amount of use for it.

50

Unassemble command For debugging, one of the main commands you will use is the Unassemble command. This command will take machine code and convert it to instructions. Addressing is the same as for previous commands with one exception: Since we are now working with code (the previous commands are mainly for data), the default register is the CS register. In a .COM program, this makes very little difference, unless you reset the DS register yourself. However, in a .EXE file, it can make a lot of difference, as the CS and DS registers are set to different values. Unassemble data can lead to some interesting results. For instance, in our example, CS:IP is set to 6897:0100. If we look at the program, we see a JMP as the first instruction, followed by data. If we just enter U, we will start at CS:IP (6897:0100) and start unassembling data. What we will get is a good instruction, followed by more or less nonsense. For instance: -U 6897:0100 6897:0103 6897:0104 6897:0105 6897:0106 6897:0107 E96B01 43 4C 4F 43 4B JMP INC DEC DEC INC DEC 026E BX SP DI BX BX

And so on, through 6897:011D. We know the INC BX, DEC SP, etc. are not valid instructions, but DEBUG doesn't, so we do have to look at the code. After working with DEBUG a little, you will be able to spot code versus data with the Unassemble command. For now, suffice to say that the first instruction will take us to CS:026E and we can start from there. If we Unassemble CS:026E, we will find something which looks a little more like what we expect. We get: -U 26E 6897:026E 6897:0272 6897:0274 6897:0276 6897:0278 6897:027B 6897:027C 6897:027E 6897:0280 6897:0282 6897:0285 6897:0289 6897:028B 6897:028D 8D167802 B409 CD21 EB05 1B5B32 4A 24B4 30CD 213C 027D0A 8D167C01 B409 CD21 CD20 LEA MOV INT JMP SBB DEC AND XOR AND ADD LEA MOV INT INT DX,[0278] AH,09 21 027D BX,[BP+DI+32] DX AL,B4 CH,CL [SI],DI BH,[DI+0A] DX,[017C] AH,09 21 20

The first few instructions look fine. But, after the JMP 027D, things start to look a little funny. Also, note that there is no instruction starting at 027D. We have instructions at 027C and 027E, but not 027D. This is again because DEBUG doesn't know data from instructions. At 027C, we should (and do) have the end of our data. But, this also translates into a valid AND instruction, so DEBUG will treat it as such. If we wanted the actual instruction at 027D, we could enter U 027D and get it, but from here, we don't know what it

51

is. what I'm trying to say is, DEBUG will do what ever you tell it. tell it to Unassemble data, it will do so to the best of its ability. have to make sure you have instructions where you think you do. DATA ENTRY COMMANDS Enter

If you So, you

The Enter command is used to place bytes of data in memory. It has two modes: Display/Modify and Replace. The difference is in where the data is specified - in the Enter command itself, or after the prompt. If you enter E address alone, you are in display/modify mode. DEBUG will prompt you one byte at a time, displaying the current byte followed by a period. At this time, you have the option of entering one or two hexadecimal characters. If you hit the space bar, DEBUG will not modify the current byte, but go on to the next byte of data. If you go too far, the hyphen (-) will back up one byte each time it is pressed. E 103 6897:0103 6897:0108 6897:0109 43.41 2E.46 40.47 4C.42 41.40 53. 4F.43 53.43. 4B.45

In this example, we entered E 103. DEBUG responded with the address and the information at that byte (43). We entered the 41 and DEBUG automatically showed the next byte of data (4C). Again, we entered 42, debug came back. The next byte was 4F, we changed it to 43. At 106, 43 was fine with us, so we just hit the space bar. DEBUG did not change the data, and went on to the following bytes. After entering 40 at location 109, we found we had entered a bad value. The hyphen key was pressed, and DEBUG backed up one byte, displaying the address and current contents. Note that it has changed from the original value (41) to the value we typed in (40). We then type in the correct value and terminate by pressing the ENTER key. As you can see, this can be very awkward, especially where large amounts of data are concerned. Also, if you need ASCII data, you have to look up each character and enter its hex value. Not easy, to be sure. That's where the Replace mod of operation comes in handy. Where the Display/Modify mode is handy for changing a few bytes at various offsets, the Replace mode is for changing several bytes of information at one time. Data can be entered in hexadecimal or character format, and multiple bytes can be entered at one time without waiting for the prompt. If you wanted to store the characters 'My name' followed by a hexadecimal 00 starting at location 103, you would enter: E 103 'My name' 0 As in the Search command, data can be entered in character (in quotes) or hexadecimal forms and can be mixed in the same command. This is the most useful way of entering large amounts of data into memory. Fill The Fill command is useful for storing a lot of data of the same data. It differs from the Enter command in that the list will be repeated until the

52

requested amount of memory is filled. If the list is longer than the amount of memory to be filled, the extra items are ignored. Like the Enter command, it will take hexadecimal or character data. Unlike the Enter command, though, large amounts of data can be stored without specifying every character. As an example, to clear 32K (8000h) of memory to 00h, you only need to enter: F 0 L 8000 0 Which translates into Fill, starting at DS:0000 for a Length of 32K (8000) with 00h. If the data were entered as '1234', the memory would be filled with the repeating string '123412341234', etc. Usually, it is better to enter small amounts of data with the Enter command, because an error in the length parameter of the Fill command can destroy a lot of work. The Enter command, however, will only change the number of bytes actually entered, minimizing the effects of a parameter error. Move The Move command does just what it says - it moves data around inside the machine. It takes bytes from with the starting address and moves it to the ending address. If you need to add an instruction into a program, it can be used to make room for the instruction. Beware, though. Any data or labels referenced after the move will not be in the same place. Move can be used to save a part of the program in free memory while you play with the program, and restore it at any time. It can also be used to copy ROM BIOS into memory, where it can be written to a file or played with to your heart's content. You can then change things around in BIOS without having to worry about programming a ROM. M 100 L 200 ES:100 This will move the data from DS:0100 to DS:02FF (Length 200) to the address pointed to by ES:0100. Later, if we want to restore the data, we can say: M ES:100 L 200 100 which will move the data back to its starting point. Unless the data has been changed while at the temporary location (ES:0100), we will restore the data to its original state. Assemble I purposely left the Assemble command to the end, as it is the most complex of the data entry commands. It will take the instructions in the assembler language and convert them to machine code directly. Some of the things it can't do, however, are: reference labels, set equates, use macros, or anything else which cannot be translated to a value. Data locations have to be referenced by the physical memory address, segment registers, if different from the defaults, must be specified, and RET instructions must specify the type (NEAR or FAR) of return to be used. Also, if an instruction references data but not registers (i.e. Mov [278],5), the Byte ptr or Word ptr overrides must be specified. One other restriction: To tell DEBUG the difference between moving 1234h into AX and moving the data from location 1234 into AX, the latter is coded as Mov AX,[1234], where the brackets indicate the reference is an addressed location. The differences between MASM and DEBUG are as follows:

53

MASM Mov Mov Mov Movs Movs Ret Ret AX,1234 AX,L1234 AX,CS:1234 Byte ptr ... Word ptr ...

DEBUG Mov AX,1234 Mov AX,[1234] CS:Mov AX,[1234] Movesb Movsw Ret Retf

Comments Place 1234 into AX Contents of add. 1234 to AX Move from offset of CS. Move byte string Move word string Near return Far return

Also, Jmp instructions will be assembled automatically to Short, Near, or Far Jmps. However, the Near and Far operands can be used to override the displacement if you do need them. Let's try a very simple routine to clear the screen. -A 100 6897:0100 6897:0103 6897:0106 6897:0109 6897:010B 6897:010D 6897:010F mov mov mov mov int int ax,600 cx,0 dx,184f bh,07 10 20

We are using BIOS interrupt 10h, which is the video interrupt. (If you would like more information on the interrupt, there is a very good description in the Technical Reference Manual.) We need to call BIOS with AX=600, BH=7, CX=0, and DX=184Fh. First we had to load the registers, which we did at in the first four instructions. The statement at offset 6897:010B actually called BIOS. The INT 20 at offset 010D is for safety only. We really don't need it, but with it in, the program will stop automatically. Without the INT 20, and if we did not stop, DEBUG would try and execute whatever occurs at 010F. If this happens to be a valid program (unlikely), we would just execute the program. Usually, though, we will find it to be invalid, and will probably hang the system, requiring a cntl-alt-del (maybe) or a power-off and on again (usually). So, be careful and double check your work! Now, we need to execute the program. To do this, enter the G command, a G followed by the enter key. If you have entered the program correctly, the screen will clear and you will get a message "Program terminated normally". (More on the Go command later). Again, I cannot stress the importance of checking your work when using the Assemble command. The commands may assemble correctly, but cause a lot of problems. This is especially important for the Jmp and Call commands; since they cause an interruption in the flow of the program, they can cause the program to jump into the middle of an instruction, causing VERY unpredictable results. I/O commands Name The Name command has just one purpose - specifying the name of a file which DEBUG is going to Load or Write. It does nothing to change memory or execute a program, but does prepare a file control block for DEBUG to work with. If you

54

are going to load a program, you can specify any parameters on the same line, just like in DOS. One difference is, the extension MUST be specified. The default is no extension. DEBUG will load or write any file, but the full file name must be entered. -n chkdsk.com /f This statement prepares DEBUG for loading the program CHKDSK.COM passing the /f switch to the program. When the Load (see below) command is executed, DEBUG will load CHKDSK.COM and set up the parameter list (/f) in the program's input area. Load The Load command has two formats. The first one will load a program which has been specified by the Name command into storage, set the various registers, and prepare for execution. Any program parameters in the Name command will be set into the Program Segment Prefix, and the program will be ready to run. If the file is a .HEX file, it is assumed to have valid hexadecimal characters representing memory values, two hexadecimal characters per byte. Files are loaded starting at CS:0100 or at the address specified in the command. For .COM. .HEX and .EXE files, the program will be loaded, the registers set, and CS:IP set to the first instruction in the program. For other files, the registers are undetermined, but basically, the segment registers are set to the segment of the PSP (100h bytes before the code is actually loaded), and BX and CX are set to the file length. Other registers are undetermined -n myprog.com -l This sequence will load myprog.com into memory, set IP to the entry point of 0100, and CX will contain 0446, the hexadecimal size of the file. The program is now ready to run. The second form of the Load command does not use the Name command. It is used to load absolute sectors from the disk (hard or soft) into memory. The sector count starts with the first sector of track 0 and continuing to the end of the track. The next sector is track 0, second side (if double sided), and continues to the end of that sector. Then, back to the first side, track 1, and so on, until the end of the disk. Up to 80h (128d) sectors can be loaded at one time. To use, you must specify starting address, drive (0=A, 1=B, etc.), starting sector, and number of sectors to load. -l 100 0 10 20 This instruction tells DEBUG to load, starting at DS:0100, from drive A, sector 10h for 20h sectors. DEBUG can sometimes be used this way to recover part of the information on a damaged sector. If you get an error, check the memory location for that data. Often times, part of the data has been transferred before the error occurs and the remainder (especially for text files) can be manually entered. Also, repetitive retrys will sometimes get the information into memory. This can then be rewritten on the same diskette (see the Write command below), or copied to the same sector on another diskette. In this way, the data on a damaged disk can sometimes be recovered.

55

Write The write command is very similar to the Load command. Both have two modes of operation, and both will operate on files or absolute sectors. As you have probably guessed, the Write command is the opposite of the Load command. Since all the parameters are the same, we will not cover the syntax in detail. However, one thing worth mentioning: When using the file mode of the Write command, the amount of data to be written is specified in BX and CX, with BX containing the high-order file size. The start address can be specified or is defaulted to CS:0100. Also, files with an extension of .EXE or .HEX cannot be written out, and error message to that effect will be displayed. If you do need to change a .EXE or .HEX file, simply rename and load it, make your changes, save it and name it back to its original filename. Input The Input command can be used to read a byte of data from any of the I/O ports in the PC. The port address can be either a one or two byte address. DEBUG will read the port, and display the contents. -i 3fd 7D This is the Line input port for the first Asynchronous adapter. Your data may be different, as it depends on the current status of the port. It indicates the data in the register at the time it was read was 7Dh. Depending on the port, this data may change, as the ports are not controlled by the PC. Output As you can probably guess, the Output command is the reverse of the Input command. You can use the Output command to send a single byte of data to a port. Note that certain ports can cause the system to hang (especially those dealing with system interrupts and the keyboard), so be careful with what you send where! -o 3fc 1 Port 3FCh is the modem control register for the first asynchronous port. Sending a 01h to this port turns on the DTR (Data Terminal Ready) bit. A 00h will turn all the bits off. If you have a modem which indicates this bit, you can watch the light flash as you turn the bit on and off. EXECUTION COMMANDS Go The Go command is used to start program execution. A very versatile command, it can be used to start the execution at any point in the program, and optionally stop at any of ten points (breakpoints) in the program. If no breakpoints are set (or the breakpoints are not executed), program execution

56

continues until termination, in which case the message "Program normally" is sent. If a breakpoint is executed, program execution current registers are displayed, and the DEBUG prompt is displayed. DEBUG commands can be executed, including the Go command to continue Note that the Go command CANNOT be terminated by Cntl-break. This the few commands which cannot be interrupted while executing. -g =100

terminated stops, the Any of the execution. is one of

The Go command without breakpoints starts program execution at the address (in this case CS:0100) in the command. The equal sign before the address is required. (Without the equal sign, the address is taken as a breakpoint.) If no starting address is specified, program execution starts at CS:IP. In this case, since no breakpoints are specified, MYPROG.COM will continue execution until the cntl-break key is pressed and the program terminates. At this time, you will get the message "Program terminated normally". Note that, after the termination message, the program should be reloaded before being executed. Also, any memory alterations (storing data, etc.) will not be restored unless the program is reloaded. -g 276 47c 528 347 This version of the control command will start the program and set breakpoints at CS:276, CS:47C, CS:528 and CS:347. These correspond to locations in MYPROG.COM after the screen is cleared, and the day, date and time are displayed, respectively. The program will stop at whichever breakpoint it hits first. Note that the second and third breakpoints will only be displayed at two times - when the program is started and at midnight. If you care to stay up (or just change the time in the computer), and set a breakpoint at 47C, t will stop when the program is started, and again at midnight. Some notes about breakpoints. The execution stops just before the instruction is executed. Setting a breakpoint at the current instruction address will not execute any instructions. DEBUG will set the breakpoint first, then try to execute the instruction, causing another breakpoint. Also, the breakpoints use Interrupt 3 to stop execution. DEBUG intercepts interrupt 3 to stop the program execution and display the registers. Finally, breakpoints are not saved between Go commands. Any breakpoints you want will be have to be set with each Go command. Trace Along the same lines as Go is the Trace command. The difference is that, while Go executes a whole block of code at one time, the Trace command executes instructions one at a time, displaying the registers after each instruction. Like the Go instruction, execution can be started at any address. The start address again must be preceeded by an equal sign. However, the Trace command also has a parameter to indicate how many instructions are to be executed. -t =100 5 This Trace command will start at CS:100 and execute five instructions. Without the address, execution will start at the current CS:IP value and continue for five instructions. T alone will execute one instruction.

57

When using Trace to follow a program, it is best to go around calls to DOS and interrupts, as some of the routines involved can be lengthy. Also, DOS cannot be Traced, and doing so has a tendency to hang the system. Therefore, Trace to the call or interrupt and Go to the next address after the call or interrupt. ARITHMETIC COMMANDS Hexarithmetic The Hexarithmetic command is handy for adding and subtracting hexadecimal numbers. It has just two parameters - the two numbers to be added and subtracted. DEBUG's response is the sum and difference of the numbers. The numbers can be one to four hexadecimal digits long. The addition and subtraction are unsigned, and no carry or borrow is shown beyond the fourth (high order) digit. -h 5 6 000B FFFF -h 5678 1234 68AC 4444 In the first example, we are adding 0005 and 0006. The sum is 000B, the difference is -1. However, since there is no carry, we get FFFF. In the second example, the sum of 5678 and 1234 is 68AC, and the difference is 4444. WRAPUP If you give it a chance, DEBUG can be a very useful tool for the IBMPC. It is almost a requirement for debugging assembler language programs, as no nice error messages are produced at run time. DEBUG does work at the base machine level, so you need some experience to use it effectively, but with practice, it will be your most useful assembler language debugging tool.

58

APPENDIX B.
The following table gives a summary of vector table and its functions. It lists some important services. s.no 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 Absolute address Interrupt vector Hex Decimal 0h 0 1h 1 2h 2 3h 3 4h 5h 6-7h 8h 9h 0Ah 0Bh 0Ch 0Dh 0Eh 0Fh 10h 11h 12h 13h 14h 15h 16h 17h 18h 19h 1Ah 4 5 6-7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 description Issued by micro-processor when divided by zero Interrupt used by debugger for single stepping Non-mask able interrupt Microprocessor interrupt that debugger uses to set breakpoints Issued by microprocessor when an arithmetic overflow occurs. Invokes the BIOS print-screen operation reserved Time of day clock issues this interrupt every clock tic This interrupt is issued whenever a key is pressed or released. Reserved Hardware interrupt line used by communication equipment. Hardware interrupt line used by communication equipment. Hardware interrupt line used by alternate printer Hardware interrupt used by diskette drives to signal that an operation is complete. Hardware interrupt line used by printer to signal for attention. Invokes the BIOS video i/o function request Invokes the BIOS equipment determination function request Invokes BIOS memory size function request. Invokes bios disk I/O request Invokes the BIOS RS-232 Serial I/O function requests. On PC-AT it invokes the AT extended service request. Invokes the BIOS keyboard I/O function request Invokes the BIOS printer I/O function request Invokes the ROM basic interpreter. Invokes the BIOS bootstrap loader Invokes the BIOS time-of-day function request 59

27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49

1Bh 1Ch

27 28

Points to code to be executed when Ctrl-break keys are pressed.. initially BIOS sets it to point to an IRET instruction.. you can change it. Points to code to be executed every timer tick, initially bios sets this to IRET instruction. You can change it.

1Dh 29 1Eh 30 1Fh 31 20h 32 21h 33 22h 34 23h 35 24h 36 25h 37 26h 38 27h 39 28h-3Fh 40-63 70h 71h 72h 73h 74h 75h 76h 77h 112 113 114 115 116 117 118 119

Invokes DOS to terminate a program. Invokes any of the DOS functions. Points to DOS termination address. Points to DOS control break address. Points to dos critical error handles. Invokes DOS absolute disk read service. Invokes DOS absolute disk write service. Invokes DOS terminate and stay resident request Reserved for DOS Hardware line IRQ8 real time clock interrupt. Hardware line IRQ9 Hardware line IRQ10 Hardware line IRQ11 Hardware line IRQ12 Hardware line IRQ13 Hardware line IRQ14 Hardware line IRQ15

60

Você também pode gostar