6

Click here to load reader

Function 2 INT 21H - BIOS Routine to Print a Character to ...ux.brookdalecc.edu/fac/engtech/andy/elt242/handouts/...Function 2 INT 21H - BIOS Routine to Print a Character to Display

  • Upload
    lekien

  • View
    214

  • Download
    2

Embed Size (px)

Citation preview

Page 1: Function 2 INT 21H - BIOS Routine to Print a Character to ...ux.brookdalecc.edu/fac/engtech/andy/elt242/handouts/...Function 2 INT 21H - BIOS Routine to Print a Character to Display

Function 2 INT 21H - BIOS Routine to Print a Character to Display

Normally, the 8086 fetches instructions from sequential memory locations and places them into an instruction queue. Many instructions simply perform a specific operation on one of the processor's registers or on the data contained in a memory location. There are, however, many times when the results of an instruction need to be interpreted. Did the last instruction set the zero flag? Was the result of the last subtraction negative? Did a 0 rotate into bit 7 of register BL? There may be many different choices to make during execution, and these choices require a number of different portions of machine code. The program needs to be able to change its execution path to respond appropriately. For this reason we need to be able to change the path of program execution by forcing the processor to fetch its next instruction from a new location. This is commonly referred to as a jump. A jump alters the contents of the processor’s instruction pointer (and sometimes its CS register as well). There are two classes of jump instructions - the unconditional (JMP address which is jump always) and Jump on Condition to an address. In assembly language, the jump instruction is how we implement a loop. Loop and Jump Instructions A loop is a section of a program that is repeated more than once. In high level languages, this could be a For - Next loop, Repeat - Until loop, or a Do - While loop. When these loops are executed, the program will remain within this section of code while a condition exists, or until a condition exists. The test that is performed is Boolean (the result is true or false). The result is based on a test of a condition. One way to implement a loop is to create a Count Controlled Loop. In this type of loop, we must have a loop control variable, which is decremented or incremented on each pass of the loop. With this type of loop, we have to initialize the loop control variable to a specific value. For example, we might initialize the counter to 10, decrement the counter on each pass, and remain in the loop until the count reaches zero. Likewise, we could clear the counter and increment it on each pass. Until the count reaches a desired value, we would remain in the loop. A second method is to use a Sentinel Controlled Loop. This might be the case where a large amount of data is read from an array until a special piece of data, called the sentinel, is encountered. This is sometimes referred to as dummy data since it is data that might not normally be encountered in the data stream... For example, if we are printing names and addresses, we would expect to encounter alphabetic and numeric data. A good choice for the sentinel would be the tilde or ~. When the sentinel is encountered, the loop is exited. The disadvantage to the Count Controlled Variable is the loop is always traversed a specific number of times. This means that we have no flexibility as to the amount of data to be accessed. With a Sentinel Control Variable we must configure a storage area for a maximum size, but placing the dummy data at the end of the data, we do not have to pad the array or traverse all elements of the array. Whichever method we use, we need to use a conditional branch instruction to either say in the loop or exit the loop. These conditional branch instructions are Jump On Condition. It works as follows: We enter the loop and do something. Then we perform a test (compare the data on to the sentinel), or increment, or decrement the loop control variable. Either way, we set or clear flags. The flags that we will use the most are:

Page 1

Page 2: Function 2 INT 21H - BIOS Routine to Print a Character to ...ux.brookdalecc.edu/fac/engtech/andy/elt242/handouts/...Function 2 INT 21H - BIOS Routine to Print a Character to Display

Function 2 INT 21H - BIOS Routine to Print a Character to Display

Sign Flag 0 = positive and 1 = negative Zero Flag 0 = not zero and 1 = zero Carry Flag 0 = no overflow and 1 = overflow Parity Flag 0 = odd and 1 = even

Loop Count Method MOV CX,10 ;load loop count into register HERE: ;Do something to process data DEC CX ;Subtract 1 from CX JNZ HERE ;If CX did not reach 0, go to beginning of loop

In the previous example, when the count reaches zero, we fall out of the loop. Here is a different method. MOV CX,10 ;load loop count into register HERE: DEC CX ;Subtract 1 from CX JZ OVER ;If CX reached 0, go to OVER ;Do something to process data JMP HERE ;Jump always to beginning of the loop OVER: ; Next Instruction here In the above example, we have two branch instructions. The first JZ OVER will exit the loop when the count reaches 0. If it is not 0, we continue through the loop. When we reach the end of the loop, we encounter JMP HERE. This is an unconditional branch or JUMP Always. We will see examples of this in the following section on BIOS Function 2. BIOS Function 2 INT 21H - Console Output Note: This is similar to Function 9 except Function 9 prints a string of text until the $ is encountered while Function 2 outputs only one character. Function 9 has a loop in the routine. To print more than one character using Function 2, the User must create the loop.

Function 2: Console Output

Entry Parameters:

Register AH: 02H

Register DL: ASCII Character

Returned Value:

Character from DL on Display

Uses INT 21H

If the ASCII character is 08H, the cursor moves back one space. If the ASCII character is 0AH, the display scrolls one line. Here is an example of Function 2. In this case, the tilde (~) is the exit character instead of the $. Since the BIOS function only outputs a single character, we must use a loop to print a string.

Page 2

Page 3: Function 2 INT 21H - BIOS Routine to Print a Character to ...ux.brookdalecc.edu/fac/engtech/andy/elt242/handouts/...Function 2 INT 21H - BIOS Routine to Print a Character to Display

Function 2 INT 21H - BIOS Routine to Print a Character to Display

.data cr equ 0dh lf equ 0ah AnyString db cr,lf,lf,”This is a text string.”,cr,lf,lf,”~” LastChar db ‘~’ In the above data segment, AnyString is an array of characters, in this case a message that we wish to print on the display. You should already know about the CR, LF characters from previous handouts. This string contains a Sentinel, the ~, and LastChar identifies the loop exit character. Now we move to the Code Segment. .code .startup mov ax,@data mov ds,ax After initializing the DS register, we identify an address pointer, and initialize it to the beginning of our array (storage buffer for the data). In our example, we are using the SI register as the address pointer to allow us to traverse (walk) the array. Since the data is ASCII (byte size), we must increment SI on each pass. SI is initialized either with the MOV or LEA instruction. si <= offset AnyString ;load address to use SI as string pointer

Here is the loop GetChar On entry, the address pointer is initialized to the offset address of GetChar in the Data Segment. Here is the Algorithm

We will read the character from memory location DS:SI into the DL register ♦ ♦ ♦ ♦ ♦ ♦

If DL contains LastChar then Jump to fini. Else move Function 2 into AH Perform a BIOS Call using INT 21H Increment the address pointer (SI) Go back to the beginning of the loop

The IF -THEN -ELSE structure is a HLL description. We cannot implement it in assembly language that way. What we must do is:

Test for the exit by comparing DL with LastChar. If they are the same, the Zero Flag is set. If they are not the same, it is cleared. So Compare is similar to the IF JZ fini is the THEN. JZ is Jump if Zero. If the zero flag is set (true) by the Compare instruction, then the next instruction is at the address indicated by the label fini. ELSE the condition was False and we perform the next instruction. We put the BIOS function in register AH

Here is the PseudoCode for the loop. GetChar: dl <= [si] ;read a string character compare dl,LastChar ;end of string? jz fini ;jump if match ah <= 2 ;display character function int 21h ;dos call si <= (si) +1 ;point to next string character jmp GetChar ;and repeat fini: ;place normal MS-DOS program termination here .exit end

Page 3

Page 4: Function 2 INT 21H - BIOS Routine to Print a Character to ...ux.brookdalecc.edu/fac/engtech/andy/elt242/handouts/...Function 2 INT 21H - BIOS Routine to Print a Character to Display

Function 2 INT 21H - BIOS Routine to Print a Character to Display

We examined how to print a string using Function 9. Let us look at the complete code for printing the same message using function 2. The Exit Character is the ~ instead of the $, and I used different labels than the previous discussion. TITLE Function 2 Example by A. H. Andersen page 60,80 ; Author Andrew H. Andersen, Jr. ; Brookdale Community College ; This program will print a string of ; ASCII characters from memory to the ; display using the MS-DOS BIOS ; Function 2 using INT 21h ; This routine sends one character at a time ; to the CRT, so we must write a loop. ; You must set up the string in a buffer ; (array) before the program is assembled, ; or the string may be created and placed ; in the buffer by some process during program ; execution. A loop exit character is placed ; at the end of the string. ; You should select a loop exit character that ; would not normally be used. Good choices are ; the $ or the ~. Remember they must be ; enclosed in quotes .MODEL SMALL .STACK 2000H .DATA CR EQU 0DH LF EQU 0AH PRNT EQU 9 DUMMY EQU “~” OurString DB CR,LF,LF,”Hello there!”, \ ;,\ means continue on next line CR,LF,LF,'~' .CODE .STARTUP MOV AX,@DATA ;initialize DS register MOV DS,AX ;indirectly ; In the following, we will use the SI ; (Source Index) register as an address pointer ; since we wish to read many characters in a loop. BEGIN: ; The following two instructions are for loop initialization MOV AH,2 ;BIOS Function 2 display character function LEA SI,OurString ;load the address pointer

Page 4

Page 5: Function 2 INT 21H - BIOS Routine to Print a Character to ...ux.brookdalecc.edu/fac/engtech/andy/elt242/handouts/...Function 2 INT 21H - BIOS Routine to Print a Character to Display

Function 2 INT 21H - BIOS Routine to Print a Character to Display

; SI will be used as an address pointer. Anytime we wish ; to use a register as an address pointer, it is enclosed ; in [ ]. We mist also initialize the pointer with ; base address of the data before we use it, and we ; must increment the pointer in the loop GetChar: MOV DL,[SI] ;read a string character CMP DL,DUMMY ;IF character is the end of string JZ Exit ;THEN jump to Exit if match INT 21H ;ELSE perform BIOS call INC SI ;point to next string character JMP GetChar ;and repeat Exit: MOV AX,4C00h ;Normal MS-DOS Exit Routine INT 21H .EXIT END The previous example used a sentinel (dummy data) to exit the loop. We could also use a loop counter to perform a loop pass one time for each character. TITLE Function 2 Example by A. H. Andersen page 60,80 ; Author Andrew H. Andersen, Jr. ; Brookdale Community College

; This program will print a string of ASCII characters from ; memory to the display using the MS-DOS BIOS Function 2 ; This example uses a loop counter. .MODEL SMALL .STACK 2000H .DATA CR EQU 0DH LF EQU 0AH PRNT EQU 9 OurString DB CR,LF,LF,”Hello there!”, \ CR,LF,LF,”~” Times EQU $-OurString ;Calaculate the number of characters .CODE .STARTUP MOV AX,@DATA ;initialize DS register MOV DS,AX ;indirectly ; In the following, we will use the SI ; (Source Index) register as an address pointer ; since we wish to read many characters in a loop.

Page 5

Page 6: Function 2 INT 21H - BIOS Routine to Print a Character to ...ux.brookdalecc.edu/fac/engtech/andy/elt242/handouts/...Function 2 INT 21H - BIOS Routine to Print a Character to Display

Function 2 INT 21H - BIOS Routine to Print a Character to Display

Page 6

BEGIN: ; The following three instructions are for loop initialization MOV AH,2 ;BIOS Function 2 display character function LEA SI,OurString ;load the address pointer MOV CX,Times ;load loop counter with times ; SI will be used as an address pointer. Anytime we wish ; to use a register as an address pointer, it is enclosed ; in [ ]. We mist also initialize the pointer with ; base address of the data before we use it, and we ; must increment the pointer in the loop GetChar: MOV DL,[SI] ;REPEAT read a string character INT 21H ;perform BIOS call INC SI ;point to next string character LOOP GetChar ;Decrement CX and loop to GetChar UNTIL CX is 0 Exit: MOV AH,4Ch ;Normal MS-DOS Exit Routine INT 21H ;End Process .EXIT END