Vous êtes sur la page 1sur 45

Deptt of Computer Science Engineering & IT,

JUIT
10B17CI421: Computer Organization Lab
Instructor: Pooja Jain

Note: - Practicals will be submitted in respective batch CL as per schedule


below. Submissions thereafter will be treated as late submissions.

Practical #1: Acquainting with the microprocessor architecture using debug.


Practical #2: Print a Character
Practical #3: Hello World Exercise
Practical #4: Get String Input Exercise
Practical #5: String instructions
Practical #6: More Strings, characters and arithmetic
Practical #7: Creating a File,
Practical #8: File Operations
Practical #9: Creating Menu Structures
Practical #10: High precision computation Calculate linear equation: ax + b = 0
Practical #11: Make all the tables related to an assembler using C/C++
Practical #12: Make the first pass of an assembler using C/C++
Practical #13: Make the first pass of an assembler using C/C++
Practical #14: Make the second pass of an assembler using C/C++
Practical #15: Make the second pass of an assembler using C/C++
Practical #16: Write a program to add two numbers in assembly language. Use the
assembler constructed to execute it
Practical #17: Write a program to print the numbers 1-100 in assembly language. Use the
assembler constructed to execute it.
Practical #18: Write a program in assembly language, to take a number from the user. If
the number is even then a message is printed in a sub program that the “number is even”. Use
the assembler constructed to execute it.

1
Practical #1 : Getting aquainted with the microprocessor architecture using debug.
Objective

The goal of this lab is to help you become acquainted with the Debug utility

If you don't understand all the concepts used in this lab, that's ok. You will learn more about
registers, data, offsets, byte swapping, and machine code in the lectures and you'll get lots of
practice with these concepts when doing assignments and other practicals.

Instructions

1. Open a DOS window on your PC. At the DOS prompt, type "debug" to start up the
debug utility.

2. The register command is used to initialize the registers used by your assembly
program. Registers are high-speed memory locations used to hold data (and in some
cases, commands). Use the following commands to set up your program:

a. Set up the data segment using "r DS" and entering a new value for DS, the
Data Segment register . Set it to equal 124Ch (the previous DS value shown in
the example is 12E6, you may see a different number).

r ds
DS 12E6
:124c

b. Set up the code segment using "r CS" and entering a new value for CS, the
Code Segment register, of 1774h.

r cs
CS 12E6
:1774

c. Set up the location within the code segment where your program will be using
"r IP" and entering a new value for IP, the Instruction Pointer register, of Ch.

r ip
IP 0100
:c

CS and IP work together to provide the address for your program. If CS =


1774 and IP = C, the program start address will be 1774C.

2
3. If you want to see the values for all the registers, use the "r" command without giving
a register name. Try it out! You should see that DS, CS, and IP have the new values
you just gave them.

4. Enter some data for your program. We want a sixteen bit value equal to 1234h. It's
going to be stored at the location offset from the start of the data segment by 4 bytes
(a byte is a 8 bit value). Addresses are specified in a Segment:Offset format where the
segment is the base of the address and the offset is the value that needs to be added to
it. Since DS points to the start of the data segment, the location four bytes from that
is specified by DS:4. This means the data is stored at the 20 bit address 124C4.

After entering 34, hit the space, then enter 12 and hit return.

e ds:4
124C:0004 00.34 00.12

You'll notice that to have 1234, you enter the 34, then the 12. This is called byte
swapping. If the 16 bit value is 1234 then it is entered 8 bits (one byte) at a time - first
the low byte, then the high byte.

5. Lets display back the data you just entered:

d ds:4

Can you see where the data shows 34 12? The left-most column gives the segment
offset - 124C:0000 in the top row (recall, DS = 124C). If you count over five spaces
(start with zero), you should see the 34 12 for DS:0004 and DS:0005.

6. Now, we're going to enter a couple of machine code instructions. Machine code is
entered just like data except that instead of putting it in the data segment (by using
DS) you're going to put it in the code segment (by using CS). Use the following
commands:

e cs:c
1774:000C 00.bb 00.04 00.00 00.8b
1774:0010 00.07

7. You can use the "u" command to decode memory into assembly instructions. Use it to
look at the two instructions you just entered:

u cs:c

What are the first two instructions?

Instruction 1: ____________________

Instruction 2: ____________________

3
They should both be MOV instructions. The first one moves (copies) 4 into the BX
register. The second one moves the data "pointed to" by the BX register into the AX
register (the [BX] means that you are using data "pointed to" by BX).

8. Use the "r" command to look at the registers again. It will show the registers and the
assembly code for the command you are about to execute. You should see something
like this:

1774:000C BB0400 MOV BX, 0004

The BB0400 is the machine code. The "MOV BX, 0004" is the assembly code. In
debug, all numbers are displayed in hexadecimal.

Now, use the "t" command to trace through your program. After hitting "t", you will
see the registers displayed again, just like when you did the register command.

What are the IP, AX, and BX register values after the first "t" command?

IP = ___________
AX = __________
BX = ___________

What are the IP, AX, and BX register values after the second "t" command?

IP = ___________
AX = __________
BX = ___________

You should notice a couple of things:

-- After each instruction, IP increments by the number of bytes of machine code that
were just executed. MOV BX, 0004 has machine code BB0400. That is three bytes
long (a byte is 8 bits). Prior to executing the instruction, IP was equal to C (12
decimal). After adding 3, IP should be equal to F (15 decimal).

-- When BX equaled 4 and you copied the value pointed to it into AX, the value in
AX was the 1234h you entered earlier. The bytes were swapped when it was copied
out of memory into the value we wanted!

9. Quit debug using the "q" command.

10. Record your observations.

4
Practical #2 : Print a Character
1. Given below is an assembly source code. Compile the program.

;=============================
;Print Character ----
;=============================
;
title PRTCHAR.ASM - Typical Minimal Assembly Program
;===============
.model small ;=
;===============
;======================
.data ;DATA + VARIABLES
;======================
print_msg1 db "Press a Key $"
CRLF db 13,10,"$"
print_msg2 db "Key pressed was: $"
key db ?
;======================
.stack 100h ;256-word stack;
;======================

;======================
.code ; START OF CODE
;======================
main: mov ax,@data ;Point ds at data segment
mov ds,ax ;Set ds:dx = far addr of msg

;Print "Press a Key:"


mov dx,offset print_msg1 ;DX = Addr of text to print
mov ah,9 ;AH = 9 "Print String Service"
int 21h ;CALL INT 21H
;to display msg
;Get Key
mov ah, 0Ch ;Clear Keyb Buffer
mov al, 01h ; Get Keypress
int 21h ;call INT 21
;AL = RETURNS ASCII
mov key,al

;Print "Carriage Return + Line Feed (CRLF)"

mov dx,offset CRLF ;DX = Addr of text to print


mov ah,9 ;AH = 9 "Print String Service"

5
int 21h ;CALL INT 21H

;Print "The key pressed was"

mov dx,offset print_msg2 ;DX = Addr of text to print


mov ah,9 ;AH = 9 "Print String Service"
int 21h ;CALL INT 21H

;Print the Character


mov dl, key ; DOS routine requires char in DL
mov ah, 02h ; set DOS function call number
int 21h ; call DOS function
;EXIT
mov ax,4c00h ;ah = code to return to DOS
int 21h ;al = 0, i.e., no error
end main

;=====================================

Your Tasks:

1. Modify the program


(a) Change the prompt Messages
(b) Make the program run 5 times using a loop.
2. Study the structure of an assembly program.
3. Explain the assembly commands used in the code.

Practical #3 : Hello World Exercise


Given below is an assembly source code. Compile the program.

;=============================
;PrintString ----
;=============================
;title PRTSTR.ASM - Typical Minimal Assembly Program
;===============
.model small ;=
;===============

;======================
.data ;DATA + VARIABLES
;======================

hello_msg db "Hello world!$"


6
;======================
.stack 100h ;256-word stack;
;======================

;======================
.code ; START OF CODE
;======================
main: mov ax,@data ;Point ds at data segment
mov ds,ax ;Set ds:dx = far addr of msg

mov dx,offset hello_msg ;DX = Addr of text to print


mov ah,9 ;AH = 9 "Print String Service"
int 21h ;CALL INT 21H
;to display msg

mov ax,4c00h ;ah = code to return to DOS


int 21h ;al = 0, i.e., no error
end main
;=============================================

Your Tasks:

1. Compile the assembly program.


2. Modify the output message.
3. Create a second message to output and printout both.
4. Make the program loop 5 times (10 messages output).

Practical #4 : Get String Input Exercise


Given below is an assembly source code. Compile the program.

;=============================
;GETSTRING ----
;=============================
;
title GETSTR.ASM - Typical Minimal Assembly Program

;===============
.model small ;=
;===============

;======================

7
.data ;DATA + VARIABLES
;======================

print_out db "the text entered was : $"


text_entered db 80h dup (0)

;======================
.stack 100h ;256-word stack;
;======================

;======================
.code ; START OF CODE
;======================
main: mov ax,@data ;Point ds at data segment
mov ds,ax ;Set ds:dx = far addr of msg

get_str: ; read string terminated by keyboard CR into array


; whose address is in bx. Terminate it with 0.

mov bx, offset text_entered

call getc ; read first character


mov byte ptr [bx], al ; In C: str[i] = al

get_loop: cmp al, 13 ; al == CR ?


je get_fin ;while al != CR

inc bx ; bx = bx + 1
call getc ; read next character
mov byte ptr [bx], al ; In C: str[i] = al
jmp get_loop ; repeat loop test
get_fin: mov byte ptr [bx], '$' ; terminate string with 0

;Print out the prompt


mov dx,OFFSET print_out
mov ah,9
int 21h

;Print out the string entered


mov dx,OFFSET text_entered
mov ah,9
int 21h

8
;EXIT
mov ax,4c00h ;ah = code to return to DOS
int 21h ;al = 0, i.e., no error

;=====================================
getc: ; read character into al
push bx
push cx
push dx ;Save register values
mov ah, 01h ; 07h DOES NOT ECHO KEYBOARD
int 21h
pop dx
pop cx
pop bx ; Restore register values
ret

end main

Your Tasks:
1. Modify the program to get two strings from the user with two different prompt
messages
2. Make the program loop 5 times

9
Practical #5 : String instructions
Given below is an assembly source code. Compile the program.

.model small
.data
CR equ 13
LF equ 10
NewLine db CR,LF,"$"

String1 db "This is a string!$"


String2 db 18 dup(0)
Diff1 db "This string is nearly the same as Diff2$"
Diff2 db "This string is nearly the same as Diff1$"
Equal1 db "The strings are equal$"
Equal2 db "The strings are not equal$"
Message db "This is a message"
SearchString db "1293ijdkfjiu938uHello983fjkfjsi98934$"

Message1 db "Using String instructions example program.$"


Message2 db CR,LF,"String1 is now: $"
Message3 db CR,LF,"String2 is now: $"
Message4 db CR,LF,"Strings are equal!$"
Message5 db CR,LF,"Strings are not equal!$"
Message6 db CR,LF,"Character was found.$"
Message7 db CR,LF,"Character was not found.$"

.stack 100h
.code

start:mov ax,@data ; ax points to of data segment


mov ds,ax ; put it into ds
mov es,ax ; put it in es too
mov ah,9 ; function 9 - display string
mov dx,OFFSET Message1 ; ds:dx points to message
int 21h ; call dos function

cld ; clear direction flag


mov si,OFFSET String1 ; make ds:si point to String1
mov di,OFFSET String2 ; make es:di point to String2
mov cx,18 ; length of strings

10
rep movsb ; copy string1 into string2

mov ah,9 ; function 9 - display string


mov dx,OFFSET Message2 ; ds:dx points to message
int 21h ; call dos function

mov dx,OFFSET String1 ; display String1


int 21h ; call DOS service

mov dx,OFFSET Message3 ; ds:dx points to message


int 21h ; call dos function

mov dx,OFFSET String2 ; display String2


int 21h ; call DOS service

mov si,OFFSET Diff1 ; make ds:si point to Diff1


mov di,OFFSET Diff2 ; make es:di point to Diff2
mov cx,39 ; length of strings
repz cmpsb ; compare strings
jnz Not_Equal ; jump if they are not the same

mov ah,9 ; function 9 - display string


mov dx,OFFSET Message4 ; ds:dx points to message
int 21h ; call dos function

jmp Next_Operation

Not_Equal:
mov ah,9 ; function 9 - display string
mov dx,OFFSET Message5 ; ds:dx points to message
int 21h ; call dos function

Next_Operation:
mov di,OFFSET SearchString ; make es:di point to string
mov cx,36 ; length of string
mov al,'H' ; character to search for
repne scasb ; find first match
jnz Not_Found

mov ah,9 ; function 9 - display string


mov dx,OFFSET Message6 ; ds:dx points to message

11
int 21h ; call dos function
jmp Lodsb_Example

Not_Found:
mov ah,9 ; function 9 - display string
mov dx,OFFSET Message7 ; ds:dx points to message
int 21h ; call dos function

Lodsb_Example:
mov ah,9 ; function 9 - display string
mov dx,OFFSET NewLine ; ds:dx points to message
int 21h ; call dos function

mov cx,17 ; length of string


mov si,OFFSET Message ; DS:SI - address of string
xor bh,bh ; video page - 0
mov ah,0Eh ; function 0Eh - write character

NextChar:
lodsb ; AL = next character in string
int 10h ; call BIOS service
loop NextChar

mov ax,4C00h ; return to DOS


int 21h

end start
Your Tasks:
1. Compile and Link this program.
2. Change the strings and check results
3 Try all string instructions learnt in the class.
4. Enter a character string from keyboard and search for a two character string to be
entered from keyboard.

12
Practical #6 : More Strings ,characters and arithmatics
Given below is an assembly source code. Compile the program.

.model small
.data
CR equ 13 ; carriage return
LF equ 10 ; line feed
firstPrompt DB CR,LF,"Enter the first number to add: $"
secondPrompt DB CR,LF,"Enter the second number: $"
answer DB CR,LF,"The answer is: $"
another DB CR,LF,"Do another? - $"
.code

.stack 100h

start:
mov ax,@data
mov ds,ax ; sets up the messages correctly

;Ask for and print the first number

mov dx,OFFSET firstPrompt


mov ah,9 ; function 9 of
int 21h ; interrupt 21h print mess to screen

xor ax,ax
int 16h ; this gets a character from the keyboard

push ax ; save ah to the stack


mov dl,al ; move al ( ascii code ) into dl
mov ah,02h ; function 2 of int 21h
int 21h

;Ask for and print the second number

mov dx,OFFSET secondPrompt


mov ah,9
int 21h ; as above print mess

xor ax,ax

13
int 16h ; get char from keyboard

push ax ; save the second number to the stack


mov dl,al
mov ah,02h
int 21h ; print ascii to screen ( no $ sign )

;Do the addition and give response

mov dx,OFFSET answer


mov ah,9
int 21h

pop ax ; get second number


mov bx,ax ; put it in bx
pop ax ; get first number
add ax,bx
sub ax,'0'
mov dx,ax ; shift result into dl
mov ah,02h
int 21h

;Do another?

mov dx,OFFSET another


mov ah,9
int 21h

xor ah,ah
int 16h
mov bl,al ; save to bl

mov dl,al
mov ah,02h
int 21h ; display character

cmp bl,'Y' ; is answer Y


je start
cmp bl,'y' ; is answer y
je start

14
mov ax,4c00h
int 21h ; terminate program

end start

Your Tasks:
1. Compile and Link this Adder program.
2. Note the numbers must add up to less than Ten (Why?)
3. Modify the program so that "c" or "C" for continue is used rather than "s" or "S" for
stop.

Practical #7 : Creating a File


Given below is an assembly source code. Compile the program.

.model small
.stack 100h
.data
new_file db "newfile"
attributes EQU 10h

.code

main: mov ax,@data


mov ds,ax

mov dx,OFFSET new_file


mov cx, attributes
mov ah,03ch
int 21h

mov ax,04c00h
int 21h

end main

Your Task:

1. Modify this program so that it deletes the file

15
2. Modify the program to create a subdirectory “MYDIR” and create a file
“myfile.txt” into this subdirectory.
3. Write Your biodata in myfile.txt..
4. Read and display contents of myfile.txt
5.

Practical #8 : File Operations


Given below are two assembly source codes Exercise a and Exercise b. Compile the
programs.

Exercise a

; -------------------------
; FILE manager
; -------------------------
.model small
.stack 100h

.data

FilePrompt db "Enter File to create: $"


filename1 db 80h dup(0)
;Handle dw ?

WriteDataPrompt db "Enter Data to Write to File: $"


WriteBuffer db 80h dup(?)

.code
;
_______________________________________________________________________
___
;____________________PROCEDURES FROM
FILELIB.ASM___________________________

EXTRN PrintMessage: PROC


EXTRN GetString:PROC
EXTRN GetChar: PROC
EXTRN CreateFile: PROC
EXTRN OpenFileRead: PROC
EXTRN NewLine: PROC
EXTRN WriteFile :PROC
EXTRN CloseFile :PROC
EXTRN Handle:PROC

16
;
_______________________________________________________________________
___

main: mov ax,@data


mov ds,ax

mov ax, OFFSET FilePrompt ;Prompt for filename


call PrintMessage

mov ax, OFFSET filename1 ;Get filename


call GetString

mov ax,OFFSET filename1 ; Create File


call CreateFile

call NewLine

mov ax,OFFSET WriteDataPrompt


call PrintMessage

mov ax, OFFSET WriteBuffer


call GetString

mov ax, OFFSET filename1


call OpenFileRead ; Returns Handle to Opened File

mov ax, OFFSET WriteBuffer


Call WriteFile

mov ax, OFFSET filename1


Call CloseFile

mov ax,04c00h
int 21h
end main

Exercise b
; -------------------------
; FILE library
; -------------------------

PUBLIC PrintMessage,GetString,GetChar,CreateFile

17
PUBLIC OpenFileRead,NewLine,WriteFile,CloseFile
Public Handle
.MODEL SMALL
.DATA
Handle dw ?
attributes EQU 10h
CR db 13
LF db 10

.code

;;SUBROUTINES USED:
;--------------------------------------------------------
PrintMessage:
push ax
push bx
push cx
push dx

mov dx,ax
mov ah,9
INT 21h

pop dx
pop cx
pop bx
pop ax

ret
;-----------------------------
GetString:
; read string terminated by keyboard CR into array
; whose address is in ax. Terminate it with 0.

push ax
push bx
push cx ; save registers

mov bx, ax

call getchar ; read first character


mov byte ptr [bx], al ; In C: str[i] = al

check_char: cmp al, 13 ; al == CR ?


je last_char ;while al != CR

18
inc bx ; bx = bx + 1
call getchar ; read next character
mov byte ptr [bx], al ; In C: str[i] = al
jmp check_char ; repeat loop test
last_char:
mov byte ptr [bx], 0 ; terminate string with 0

pop cx
pop bx
pop ax ; restore registers
ret
;==========================================
getchar:
push bx
push cx
push dx
mov ah,1
int 21h

pop dx
pop cx
pop bx
ret
;==========================================
CreateFile:
push ax
push bx
push cx
push dx

mov dx,ax
mov cx, attributes
mov ah,03ch
int 21h
mov Handle,ax
pop dx
pop cx
pop bx
pop ax
ret
;==========================================

OpenFileread:
push ax
push bx
push cx

19
push dx

mov dx,ax
mov ah, 03dh ;Open File
mov al,2 ; 2=Read/Write
INT 21h
mov Handle,ax ; Save Handle to Variable
pop dx
pop cx
pop bx
pop ax
ret
;==========================================
NewLine:

push ax
push dx
mov dl,CR
mov ah,2
int 21h
mov dl,LF
mov ah,2
int 21h

pop dx
pop ax
ret
;==========================================
Writefile:
push ax
push bx
push cx
push dx
mov bx,Handle
mov dx,ax
mov ah,40h
mov cx,80h
int 21h
pop dx
pop cx
pop bx
pop ax

ret
;==========================================
CloseFile:

20
push ax
push bx
push cx
push dx
mov bx,ax
mov ah, 03eh ;Close File
INT 21h

pop dx
pop cx
pop bx
pop ax
ret
;==========================================

end

Your Tasks:

1. Assemble manager.asm and filelib.asm


2. link manager.obj and filelib.obj together to create manager.exe
3. Write your own PROCEDURES in FILELIB.ASM and Call them from
MANAGER.ASM

21
Practical #9 : Menu Structures
Given below are two assembly source codes Exercise a and Exercise b. Compile the
programs.

Exercise a

;
===============================================================
===
;=== MENU PROGRAM ===================
;
===============================================================
===
.model small ; MODEL TYPE

.stack ; STACK SEGMENT

.data ; DATA SEGMENT


;
===============================================================
===
;
===============================================================
===

LineNo db ? ;variable
ColNo db ? ;variable
colour db ? ;variable
Test1 db " GOODBYE ",0
err1 DB " ERROR!! $"
store DB 4000 dup(?) ; save contents of screen

Buffer DB 80 dup (?) ; buffer to store data

OnePressed db "One was selected : "


TwoPressed db "Two was selected : "
ThreePressed db "Three was selected : "
FourPressed db "Four was selected : "
FivePressed db "Five was selected : "
XPressed db "eXit was selected : "
;___________________________________________________________________
;_____________________ FILE STUFF __________________________________

;____________________________________________________________________
22
;_____________________ SCREEN _______________________________________
Text4 db " "
Text db " x) exit "
Text2 db " 1) Option 1 "
Text3 db " 2) Option 2 "
Text6 db " 3) Option 3 "
Text5 db " 4) Option 4 "
Text7 db " 5) Option 5 "
Box1 db "ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ"
Box2 db "Û"
;
_______________________________________________________________________
___
;
_______________________________________________________________________
___
.code ; CODE SEGMENT
;
_______________________________________________________________________
___
;____________________PROCEDURES FROM IOLIB
________________________________

EXTRN delay: PROC


EXTRN putchar:PROC
EXTRN puts: PROC
EXTRN getc: PROC
EXTRN blank: PROC
EXTRN cursor: PROC
EXTRN get_str :PROC
EXTRN getchar :PROC
;
_______________________________________________________________________
___
;
_______________________________________________________________________
___
;
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
<<
START_MAIN: ;<<<<< START >>>>>
;<<<<<<<<<>>>>>>>>

mov ax,@data ; set up ds as the segment for data


mov es,ax ; put this in es
call DISPLAY_MENU

23
;------<<<<<<<<<<<<<<<< GET KEYBOARD INPUT
>>>>>>>>>>>>>>>----------------
lop: call DISPLAY_MENU
call getc ; does not echo keyboard hit
;-------------------------------------------------------------------------
;
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
<<<<<<<<<<<
cmp al,'X' ; is al= <<<<<<<<_X_>>>>>>>
jz exit ; if yes then exit <<<<<<<<<<<<<<<<<<<
cmp al,'x' ; is al= ?
jz exit ; if yes then same
;-------------------------------------------------------------------------
mov dh,13 ; row position of cursor
mov dl,26 ; col position
call cursor
;-------------------------------------------------------------------------
;
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
<<<<<<<<<<<
; <<<<<<_1_ <<<
cmp al,'1' ; is al= 1 PRESSED <<<<<<<<<<<<<<<<<<<
jnz OVER
mov bp,OFFSET OnePressed
call DispMess
jmp lop
;-------------------------------------------------------------------------
;
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
<<<<<<<<<<<
; <<<<<<_2_ <<<
OVER: cmp al,'2' ; is al= 2 PRESSED <<<<<<<<<<<<<<<<<<
jne OVER1 ;
mov bp,OFFSET TwoPressed
call DispMess
jmp lop
;-------------------------------------------------------------------------
;
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
<<<<<<<<<<<
OVER1: cmp al,'3' ; is al= 3 PRESSED <<<<<<_3_ <<<
jne OVER2 ; <<<<<<<<<<<<<<<<<<
mov bp,OFFSET ThreePressed
call DispMess
jmp lop

24
;-------------------------------------------------------------------------
;
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
<<<<<<<<<<<
; <<<<<<_4_<
OVER2: cmp al,'4' ; is al= 4 PRESSED <<<<<<<<<<<<<<<<<<
jne OVER3
mov bp,OFFSET FourPressed
call DispMess
jmp lop
;-------------------------------------------------------------------------
;
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
<<<<<<<<<<<
; <<<<<<_5_ <<<
OVER3: cmp al,'5' ; <<<<<<<<<<<<<<<<<<<
jne OVER4
mov bp,OFFSET FivePressed
call DispMess
OVER4:JMP LOP ; REPEAT UNTIL SICK OF IT!
;-------------------------------------------------------------------------
;
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
<<<<<<<<<<<
exit: mov bp, OFFSET XPRESSED
call DispMess

call Delay
call Delay
call Delay

mov ax,4C00h ; return to DOS <<<<<<<<< EXIT <<<<<


call blank ; <<<<<<<<<<<<<<<<<<<<
int 21h ; exit program
ret ;
;------------------------------------------------------------

;<<<<<<<<<<<<|===================|<<<<<<<<<<<<<<<<<<<<<<<<<<<
;============| CALLED PROCEDURES |===========================
;>>>>>>>>>>>>|===================|>>>>>>>>>>>>>>>>>>>>>>>>>>>

;============================================================
; MENU SCREEN PROCEDURE <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

DISPLAY_MENU:

25
push bp

call bg ; writes background box to screen


call tb ; writes top and bottom border to box
call bs ; paints sides of box
;----------------------------------------------------------
mov LineNo,10 ;print menu
mov ColNo,25
MOV COLOUR,26
;------<<<<<<<<<<<<<<<< DISPLAY MENU TEXT >>>>>>>>>>>>>>>>-
mov bp,OFFSET Text2 ;ES:BP points to message
call Disp ;displays intro message
;----------------------------------------------------------
inc LineNo
mov bp,OFFSET Text3 ;ES:BP points to message
call Disp ;displays intro message
;----------------------------------------------------------
inc LineNo
mov bp,OFFSET Text6 ;ES:BP points to message
call Disp ;displays intro message
;----------------------------------------------------------
inc LineNo
mov bp,OFFSET Text5 ;ES:BP points to message
call Disp ;displays intro message
;----------------------------------------------------------
inc LineNo
mov bp,OFFSET Text7 ;ES:BP points to message
call Disp ;displays intro message

;----------------------------------------------------------
mov LineNo,15
mov bp,OFFSET Text ;displays intro message
call Disp
pop bx
ret
;----------------------------------------------------------
;==========================================================
; SCR BLANK PROCEDURE <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
;==========================================================
blank_scr:
push ax
push bx
push cx
push dx
CALL BLANK
pop dx

26
pop cx
pop bx
pop ax
ret
;----------------------------------------------------------

;============================== paints BOX


bg: mov cx,8
mov LineNo,9
mov bp,OFFSET Text4 ; ES:BP points to message

mov ColNo,25
MOV COLOUR,26
again: push cx
call disp
pop cx

inc LineNo
loop again
ret
;============================== paints BOX Top and bottom
TB: mov cx,2
mov LineNo,8
mov bp,OFFSET Box1 ; ES:BP points to message
mov ColNo,25
MOV COLOUR,15

B2: push cx
call disp
pop cx
add LineNo,8
loop B2
ret
;--------------------------------------------------------------
;============================== paints BOX sides
BS: mov cx,9
mov LineNo,8
mov bp,OFFSET Box2 ; ES:BP points to message
MOV COLOUR,15

B3: push cx
mov ColNo,24 ; do the left side
call dis2

27
mov ColNo,55 ; do the right side
call dis2

pop cx
inc LineNo ; move to the next line
loop B3
ret

;--------------------------------------------------------------
; display a string using int 10 function 13h
;--------------------------------------------------------------
Disp: push ax
push bx
push cx
push dx
mov ah,13h ; function 13 - write string
mov al,01h ; attrib in bl,move cursor
xor bh,bh ; video page 0

mov bl,colour ; attribute 4 - magenta


mov cx,30 ; length of string

mov dh,LineNo ; row to put string


mov dl,ColNo ; column to put string

int 10h ; call BIOS service


;--------------------------------------------------------------
pop dx
pop cx
pop bx
pop ax
ret ; end proc
;------------------------------------------------------------------
;--------------------------------------------------------------
; procedure to display sides of box
;--------------------------------------------------------------
Dis2: push ax
push bx
push cx
push dx
mov ah,13h ; function 13 - write string
mov al,01h ; attrib in bl,move cursor
xor bh,bh ; video page 0

mov bl,colour ; attribute 4 - magenta

28
mov cx,1 ; length of string

mov dh,LineNo ; row to put string


mov dl,ColNo ; column to put string

int 10h ; call BIOS service


pop dx
pop cx
pop bx
pop ax

ret ; end proc


;------------------------------------------------------------------
;--------------------------------------------------------------
;--------------------------------------------------------------
; displays a string on the screen not using ints
;--------------------------------------------------------------
;PUSH AND POP REGISTERS WHEN USING THIS PROCEDURE
;--------------------------------------------------------------
put_str: ; display string terminated by 0
; whose address is in ax
push ax
push bx
push cx
push dx ; save registers

mov ax, @data


mov ds, ax
mov ax, OFFSET buffer;Test1

mov bx, ax ; store address in bx


mov al, byte ptr [bx] ;

put_loop: cmp al, 0 ; al == 0 ?


je put_fin ; while al != 0
call putchar ; display character
inc bx ; bx = bx + 1
mov al, byte ptr [bx] ;
jmp put_loop ; repeat loop test
put_fin:
pop dx
pop cx
pop bx
pop ax ; restore registers
ret
;==============================================================

29
DispMess: push ax
push bx
push cx
push dx
mov ah,13h ; function 13 - write string
mov al,01h ; attrib in bl,move cursor
xor bh,bh ; video page 0

mov bl,colour ; attribute 4 - magenta


mov cx,24 ; length of string

mov dh,23 ; row to put string


mov dl,20 ; column to put string

int 10h ; call BIOS service


;--------------------------------------------------------------
pop dx
pop cx
pop bx
pop ax
ret ; end proc

;--------------------------------------------------------------
;--------------------------------------------------------------
;--------------------------------------------------------------
;--------------------------------------------------------------
end START_MAIN ; end prog
;--------------------------------------------------------------
;--------------------------------------------------------------
;--------------------------------------------------------------

Exercise b

; -------------------------
; IO library
; -------------------------

PUBLIC putchar,getchar,getc,blank,cursor,cursor2
PUBLIC putstring,getstring,newline,puts,delay,get_str

.MODEL SMALL

.DATA
sub_tot DW 0 ;intermediate value
flag DB 0 ;general purpose flag

30
LineNo db ?

; NEW <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
;
.CODE
; -----------------------------------------------------------------------
delay: push ax
push bx
push cx
push dx ; creates 1 second delay
mov cx,800
delay0: push cx
mov cx, 0ffffh
delay1: loop delay1
pop cx
loop delay0
pop dx
pop cx
pop bx
pop ax
ret ;end proc
;--------------------------------------------------------------
putchar: push ax ;preserve registers used
push dx
mov dl, al ;DOS routine requires char in DL
mov ah, 02h ;set DOS function call number
int 21h ;call DOS function
pop dx
pop ax
ret
; -----------------------------------------------------------------------
getchar: mov ah, 0Ch ;set DOS function call numbers
mov al, 01h
int 21h ;call DOS function
ret ;return with char in AL
; -----------------------------------------------------------------------
; -----------------------------------------------------------------
putstring: push ax
push bx ; save registers use

putstring1: mov al,DS:[bx] ; get next string char


cmp al, 0

31
je putstring2 ; if end of string exit
call putchar ; else print char

inc bx ; increment string pointer


jmp putstring1 ; repeat loop

putstring2: pop bx
pop ax ; restore registers

ret
; -------------------------------------------------------------
getstring: push ax
push bx ; preserve registers

getstring1: call getchar ; get a character


cmp al, 0Dh ; if carriage-return
je getstring2 ; exit

mov DS:[bx], al ; save char in string buffer


inc bx ; adjust string pointer
jmp getstring1 ; repeat loop

getstring2: mov BYTE PTR DS:[bx], 0 ; add string terminator


pop bx
pop ax
ret
; ---------------------------------------------------------------
puts: ; display a string terminated by $
; ax contains address of string
push ax
push bx
push cx
push dx ;Save register values

mov dx, ax
mov ah, 9
int 21h ; call ms-dos to output string

pop dx
pop cx
pop bx
pop ax ; Restore register values
ret
;--------------------------------------------------------------
newline: push ax

32
mov al, 10
call putchar
mov al, 13
call putchar

pop ax
ret
; -------------------------------------------------------------
getc: ; read character into al
push bx
push cx
push dx ;Save register values
mov ah, 01h ; 07h DOES NOT ECHO KEYBOARD
int 21h
pop dx
pop cx
pop bx ; Restore register values
ret
;--------------------------------------------------------------
blank: ;blanks screen
push ax
push bx
push cx
push dx

mov ah,2
mov bh,0
mov dx,0
int 10h

xor bh,bh
mov ah,8
int 10h

mov bl,bh
mov bh,ah
sub cx,cx
mov dx,184fh ;18h = 24 rows, 4f = 79 coulums
mov ax,0600h
int 10h

pop dx
pop cx
pop dx
pop ax
ret

33
; -------------------------------------------------------------
cursor:
push bx
push ax ;save these registers in case the calling
;program needs them
xor bh,bh

mov ah,02h
int 10h ;cursor move interrupt

pop ax
pop bx
ret
cursor2:
push bx
push ax ;save these registers in case the calling
;program needs them
xor bh,bh

mov ah,03h
int 10h ;cursor move interrupt

pop ax
pop bx
ret

; -------------------------------------------------------------
get_str: ; read string terminated by keyboard CR into array
; whose address is in ax. Terminate it with 0.

push bx
push bx
push cx ; save registers

mov bx, ax

call getc ; read first character


mov byte ptr [bx], al ; In C: str[i] = al

get_loop: cmp al, 13 ; al == CR ?


je get_fin ;while al != CR

inc bx ; bx = bx + 1
call getc ; read next character
mov byte ptr [bx], al ; In C: str[i] = al
jmp get_loop ; repeat loop test

34
get_fin: mov byte ptr [bx], 0 ; terminate string with 0

pop dx
pop cx
pop bx ; restore registers
ret
; -------------------------------------------------------------

END

Your Tasks:
1. Assemble menu.asm then
2. assemble iolib.asm using MASM
3. c:\hardware> LINK menu.obj iolib.obj to create menu.exe
4. MODIFY THE OPTIONS TO DO OTHER TASKS, NOT JUST PRINTING A
MESSAGE
5. Write how the menu was created.

Practical #10 : High precision computation-Calculate linear equation: ax + b =


0

Given below is assembly source code. Compile the program.

;float.asm
; calculate equation with high precision without math coprocessor
; this program calculates linear equation: ax + b = 0
; the result is printed with floating point.
; for example: a = 7, b = 2
; x = -0.28571428....
name "float"
precision = 30 ; max digits after the dot.
dseg segment 'data'
cr equ 0Dh
lf equ 0Ah
new_line equ 0Dh,0Ah, '$'
mess0 db 'calculation of ax + b = 0', new_line
mess1 db 'enter a (-32768..32767)!', new_line
mess2 db lf, cr, 'enter b (-32768..32767)!', new_line
mess3 db cr, lf, cr, lf, 'data:', '$'
mess4 db cr, lf, ' a = ', '$'
mess5 db cr, lf, ' b = ', '$'

35
mess6 db cr, lf, 'result: ', cr, lf, ' x = ', '$'
mess7 db cr, lf, cr, lf, 'no solution!', new_line
mess8 db cr, lf, cr, lf, 'infinite number of solutions!', new_line
error db cr, lf, 'the number is out of range!', new_line
twice_nl db new_line, new_line
make_minus db ? ; used as a flag in procedures.
a dw ?
b dw ?
ten dw 10 ; used as multiplier.
four dw 4 ; used as divider.
dseg ends

sseg segment stack 'stack'


dw 100h dup(?)
sseg ends

cseg segment 'code'


;*******************************************************************
start proc far
; store return address to os:
push ds
xor ax, ax
push ax

; set segment registers:


mov ax, dseg
mov ds, ax
mov es, ax

; welcome message:
lea dx, mess0
call puts ; display the message.

; ask for 'a' :


lea dx, mess1
call puts ; display the message.
call scan_num ; input the number into cx.
mov ds:a, cx

; ask for 'b' :


lea dx, mess2
call puts ; display the message.
call scan_num ; input the number into cx.
mov ds:b, cx

; print the data:

36
lea dx, mess3
call puts

lea dx, mess4


call puts
mov ax,ds:a
call print_num ; print ax.

lea dx, mess5


call puts
mov ax,ds:b
call print_num ; print ax.

; check data:
cmp ds:a, 0
jne soluble ; jumps when a<>0.
cmp ds:b, 0
jne no_solution ; jumps when a=0 and b<>0.
jmp infinite ; jumps when a=0 and b=0.
soluble:

; calculate the solution:


; ax + b = 0 -> ax = -b -> x = -b/a

neg ds:b

mov ax,ds:b

xor dx, dx

; check the sign, make dx:ax negative if ax is negative:


cmp ax, 0
jns not_singned
not dx
not_singned:
mov bx,ds:a ; divider is in bx.

; '-b' is in dx:ax.
; 'a' is in bx.

idiv bx ; ax = dx:ax / bx (dx - remainder).

; 'x' is in ax.
; remainder is in dx.

37
push dx ; store the remainder.

lea dx, mess6


call puts

pop dx

; print 'x' as float:


; ax - whole part
; dx - remainder
; bx - divider
call print_float

jmp end_prog
no_solution:
lea dx, mess7
call puts
jmp end_prog
infinite:
lea dx, mess8
call puts
end_prog:
lea dx, twice_nl
call puts

; wait for any key....


mov ah, 0
int 16h

ret
start endp

;***************************************************************

; prints number in ax and it's fraction in dx.


; used to print remainder of 'div/idiv bx'.
; ax - whole part.
; dx - remainder.
; bx - the divider that was used to get the remainder from divident.
print_float proc near
push cx
push dx

; because the remainder takes the sign of divident


; its sign should be inverted when divider is negative

38
; (-) / (-) = (+)
; (+) / (-) = (-)
cmp bx, 0
jns div_not_signed
neg dx ; make remainder positive.
div_not_signed:

; print_num procedure does not print the '-'


; when the whole part is '0' (even if the remainder is
; negative) this code fixes it:
cmp ax, 0
jne checked ; ax<>0
cmp dx, 0
jns checked ; ax=0 and dx>=0
push dx
mov dl, '-'
call write_char ; print '-'
pop dx
checked:

; print whole part:


call print_num

; if remainder=0, then no need to print it:


cmp dx, 0
je done

push dx
; print dot after the number:
mov dl, '.'
call write_char
pop dx

; print digits after the dot:


mov cx, precision
call print_fraction
done:
pop dx
pop cx
ret
print_float endp

;***************************************************************

; prints dx as fraction of division by bx.


; dx - remainder.

39
; bx - divider.
; cx - maximum number of digits after the dot.
print_fraction proc near
push ax
push dx
next_fraction:
; check if all digits are already printed:
cmp cx, 0
jz end_rem
dec cx ; decrease digit counter.

; when remainder is '0' no need to continue:


cmp dx, 0
je end_rem

mov ax, dx
xor dx, dx
cmp ax, 0
jns not_sig1
not dx
not_sig1:

imul ds:ten ; dx:ax = ax * 10

idiv bx ; ax = dx:ax / bx (dx - remainder)

push dx ; store remainder.


mov dx, ax
cmp dx, 0
jns not_sig2
neg dx
not_sig2:
add dl, 30h ; convert to ascii code.
call write_char ; print dl.
pop dx

jmp next_fraction
end_rem:
pop dx
pop ax
ret
print_fraction endp

;***************************************************************

; this procedure prints number in ax,

40
; used with print_numx to print "0" and sign.
; this procedure also stores the original ax,
; that is modified by print_numx.
print_num proc near
push dx
push ax

cmp ax, 0
jnz not_zero

mov dl, '0'


call write_char
jmp printed

not_zero:
; the check sign of ax,
; make absolute if it's negative:
cmp ax, 0
jns positive
neg ax

mov dl, '-'


call write_char
positive:
call print_numx
printed:
pop ax
pop dx
ret
print_num endp

;***************************************************************

; prints out a number in ax (not just a single digit)


; allowed values from 1 to 65535 (ffff)
; (result of /10000 should be the left digit or "0").
; modifies ax (after the procedure ax=0)
print_numx proc near
push bx
push cx
push dx

; flag to prevent printing zeros before number:


mov cx, 1

mov bx, 10000 ; 2710h - divider.

41
; check if ax is zero, if zero go to end_show
cmp ax, 0
jz end_show

begin_print:

; check divider (if zero go to end_show):


cmp bx,0
jz end_show

; avoid printing zeros before number:


cmp cx, 0
je calc
; if ax<bx then result of div will be zero:
cmp ax, bx
jb skip
calc:
xor cx, cx ; set flag.

xor dx, dx
div bx ; ax = dx:ax / bx (dx=remainder).

; print last digit


; ah is always zero, so it's ignored
push dx
mov dl, al
add dl, 30h ; convert to ascii code.
call write_char
pop dx

mov ax, dx ; get remainder from last div.

skip:
; calculate bx=bx/10
push ax
xor dx, dx
mov ax, bx
div ds:ten ; ax = dx:ax / 10 (dx=remainder).
mov bx, ax
pop ax

jmp begin_print

end_show:

42
pop dx
pop cx
pop bx
ret
print_numx endp

;***************************************************************

; displays the message (dx-address)


puts proc near
push ax
mov ah, 09h
int 21h
pop ax
ret
puts endp

;*******************************************************************

; reads char from the keyboard into al


; (modifies ax!!!)
read_char proc near
mov ah, 01h
int 21h
ret
read_char endp

;***************************************************************

; gets the multi-digit signed number from the keyboard,


; result is stored in cx
scan_num proc near
push dx
push ax

xor cx, cx

; reset flag:
mov ds:make_minus, 0

next_digit:

call read_char

; check for minus:


cmp al, '-'

43
je set_minus

; check for enter key:


cmp al, cr
je stop_input

; multiply cx by 10 (first time the result is zero)


push ax
mov ax, cx
mul ds:ten ; dx:ax = ax*10
mov cx, ax
pop ax

; check if the number is too big


; (result should be 16 bits)
cmp dx, 0
jne out_of_range

; convert from ascii code:


sub al, 30h

; add al to cx:
xor ah, ah
add cx, ax
jc out_of_range ; jump if the number is too big.

jmp next_digit

set_minus:
mov ds:make_minus, 1
jmp next_digit

out_of_range:
lea dx, error
call puts

stop_input:
; check flag:
cmp ds:make_minus, 0
je not_minus
neg cx
not_minus:

pop ax
pop dx
ret

44
scan_num endp

;***************************************************************

; prints out single char (ascii code should be in dl)


write_char proc near
push ax
mov ah, 02h
int 21h
pop ax
ret
write_char endp

;***************************************************************

cseg ends
end start

Your Tasks:

1. Assemble and link float.asm.


2. modify the program to solve for ax+b=c.
3. Analyse the commands used.
4. Your comments on the precision.

45