Post on 30-Mar-2015
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 CharacterPractical #3: Hello World ExercisePractical #4: Get String Input ExercisePractical #5: String instructions Practical #6: More Strings, characters and arithmeticPractical #7: Creating a File, Practical #8: File OperationsPractical #9: Creating Menu Structures Practical #10: High precision computation Calculate linear equation: ax + b = 0Practical #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 itPractical #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 dsDS 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 csCS 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 ipIP 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.
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
2
(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:4124C: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:c1774: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: ____________________
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:
3
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.
Practical #2 : Print a Character 1. Given below is an assembly source code. Compile the program.
;=============================;Print Character ----;=============================
4
;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 printmov ah,9 ;AH = 9 "Print String Service"int 21h ;CALL INT 21H
;to display msg;Get Key
mov ah, 0Ch ;Clear Keyb Buffermov al, 01h ; Get Keypressint 21h ;call INT 21
;AL = RETURNS ASCIImov key,al
;Print "Carriage Return + Line Feed (CRLF)"
mov dx,offset CRLF ;DX = Addr of text to printmov ah,9 ;AH = 9 "Print String Service"int 21h ;CALL INT 21H
;Print "The key pressed was"
mov dx,offset print_msg2 ;DX = Addr of text to printmov ah,9 ;AH = 9 "Print String Service"int 21h ;CALL INT 21H
5
;Print the Charactermov dl, key ; DOS routine requires char in DLmov ah, 02h ; set DOS function call numberint 21h ; call DOS function
;EXITmov ax,4c00h ;ah = code to return to DOSint 21h ;al = 0, i.e., no errorend 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!$"
;======================.stack 100h ;256-word stack;;======================
;======================.code ; START OF CODE ;======================
6
main: mov ax,@data ;Point ds at data segmentmov ds,ax ;Set ds:dx = far addr of msg
mov dx,offset hello_msg ;DX = Addr of text to printmov ah,9 ;AH = 9 "Print String Service"int 21h ;CALL INT 21H
;to display msg
mov ax,4c00h ;ah = code to return to DOSint 21h ;al = 0, i.e., no errorend 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 ;=;===============
;======================.data ;DATA + VARIABLES ;======================
print_out db "the text entered was : $"text_entered db 80h dup (0)
;======================.stack 100h ;256-word stack;
7
;======================
;======================.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 charactermov 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 + 1call getc ; read next charactermov byte ptr [bx], al ; In C: str[i] = aljmp get_loop ; repeat loop test
get_fin: mov byte ptr [bx], '$' ; terminate string with 0
;Print out the promptmov dx,OFFSET print_outmov ah,9 int 21h
;Print out the string enteredmov dx,OFFSET text_enteredmov ah,9int 21h
;EXITmov ax,4c00h ;ah = code to return to DOSint 21h ;al = 0, i.e., no error
;=====================================getc: ; read character into al
8
push bxpush cxpush dx ;Save register valuesmov ah, 01h ; 07h DOES NOT ECHO KEYBOARD int 21h pop dxpop cxpop bx ; Restore register valuesret
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
.dataCR equ 13LF equ 10NewLine 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 segmentmov ds,ax ; put it into dsmov es,ax ; put it in es toomov ah,9 ; function 9 - display stringmov dx,OFFSET Message1 ; ds:dx points to messageint 21h ; call dos function
cld ; clear direction flagmov si,OFFSET String1 ; make ds:si point to String1mov di,OFFSET String2 ; make es:di point to String2mov cx,18 ; length of strings
10
rep movsb ; copy string1 into string2
mov ah,9 ; function 9 - display stringmov dx,OFFSET Message2 ; ds:dx points to messageint 21h ; call dos function
mov dx,OFFSET String1 ; display String1int 21h ; call DOS service
mov dx,OFFSET Message3 ; ds:dx points to messageint 21h ; call dos function
mov dx,OFFSET String2 ; display String2int 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 stringsrepz cmpsb ; compare stringsjnz Not_Equal ; jump if they are not the same
mov ah,9 ; function 9 - display stringmov dx,OFFSET Message4 ; ds:dx points to messageint 21h ; call dos function
jmp Next_Operation
Not_Equal:mov ah,9 ; function 9 - display stringmov dx,OFFSET Message5 ; ds:dx points to messageint 21h ; call dos function
Next_Operation:mov di,OFFSET SearchString ; make es:di point to stringmov cx,36 ; length of stringmov al,'H' ; character to search forrepne scasb ; find first matchjnz Not_Found
mov ah,9 ; function 9 - display stringmov dx,OFFSET Message6 ; ds:dx points to message
11
int 21h ; call dos functionjmp Lodsb_Example
Not_Found:mov ah,9 ; function 9 - display stringmov dx,OFFSET Message7 ; ds:dx points to messageint 21h ; call dos function
Lodsb_Example:mov ah,9 ; function 9 - display stringmov dx,OFFSET NewLine ; ds:dx points to messageint 21h ; call dos function
mov cx,17 ; length of stringmov si,OFFSET Message ; DS:SI - address of stringxor bh,bh ; video page - 0mov ah,0Eh ; function 0Eh - write character
NextChar:lodsb ; AL = next character in stringint 10h ; call BIOS serviceloop NextChar
mov ax,4C00h ; return to DOSint 21h
end startYour 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.txt5.
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 21hend main
Exercise b; -------------------------; FILE library; -------------------------
PUBLIC PrintMessage,GetString,GetChar,CreateFilePUBLIC OpenFileRead,NewLine,WriteFile,CloseFile
17
Public Handle.MODEL SMALL.DATA Handle dw ? attributes EQU 10h CR db 13 LF db 10 .code
;;SUBROUTINES USED:;--------------------------------------------------------PrintMessage: push ax
push bxpush cxpush dx
mov dx,ax mov ah,9 INT 21h
pop dxpop cxpop bxpop ax
ret;-----------------------------GetString: ; read string terminated by keyboard CR into array ; whose address is in ax. Terminate it with 0.
push axpush bxpush 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
inc bx ; bx = bx + 1
18
call getchar ; read next character mov byte ptr [bx], al ; In C: str[i] = al jmp check_char ; repeat loop testlast_char: mov byte ptr [bx], 0 ; terminate string with 0
pop cxpop bxpop ax ; restore registers
ret;==========================================getchar: push bx
push cxpush dx
mov ah,1 int 21h
pop dxpop cxpop bx
ret;==========================================CreateFile: push ax
push bxpush cxpush dx
mov dx,ax mov cx, attributes mov ah,03ch int 21h mov Handle,ax pop dx
pop cxpop bxpop ax
ret;==========================================
OpenFileread: push ax
push bxpush cxpush dx
19
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 cxpop bxpop ax
ret;==========================================NewLine:
push axpush dx
mov dl,CR mov ah,2 int 21h mov dl,LF mov ah,2 int 21h
pop dxpop ax
ret;==========================================Writefile: push ax
push bxpush cxpush dx
mov bx,Handle mov dx,ax mov ah,40h mov cx,80h int 21h pop dx
pop cxpop bxpop ax
ret;==========================================CloseFile: push ax
20
push bxpush cxpush dx
mov bx,ax mov ah, 03eh ;Close File INT 21h
pop dxpop cxpop bxpop 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 ",0err1 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 __________________________________
;____________________________________________________________________;_____________________ SCREEN _______________________________________
Text4 db " "Text db " x) exit "Text2 db " 1) Option 1 "
22
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: PROCEXTRN putchar:PROCEXTRN puts: PROCEXTRN getc: PROCEXTRN blank: PROCEXTRN cursor: PROCEXTRN get_str :PROCEXTRN getchar :PROC
;__________________________________________________________________________ ;__________________________________________________________________________ ;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<START_MAIN: ;<<<<< START >>>>>
;<<<<<<<<<>>>>>>>>
mov ax,@data ; set up ds as the segment for datamov es,ax ; put this in escall DISPLAY_MENU
;------<<<<<<<<<<<<<<<< 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 <<<<<<<<<<<<<<<<<<<
23
cmp al,'x' ; is al= ?jz exit ; if yes then same
;-------------------------------------------------------------------------mov dh,13 ; row position of cursor mov dl,26 ; col positioncall cursor
;-------------------------------------------------------------------------;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< ; <<<<<<_1_ <<<
cmp al,'1' ; is al= 1 PRESSED <<<<<<<<<<<<<<<<<<<jnz OVERmov bp,OFFSET OnePressedcall DispMessjmp lop
;-------------------------------------------------------------------------;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< ; <<<<<<_2_ <<< OVER: cmp al,'2' ; is al= 2 PRESSED <<<<<<<<<<<<<<<<<<
jne OVER1 ;mov bp,OFFSET TwoPressedcall DispMessjmp lop
;-------------------------------------------------------------------------;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< OVER1: cmp al,'3' ; is al= 3 PRESSED <<<<<<_3_ <<<
jne OVER2 ; <<<<<<<<<<<<<<<<<<mov bp,OFFSET ThreePressedcall DispMessjmp lop
;-------------------------------------------------------------------------;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< ; <<<<<<_4_<OVER2: cmp al,'4' ; is al= 4 PRESSED <<<<<<<<<<<<<<<<<<
jne OVER3mov bp,OFFSET FourPressedcall DispMessjmp lop
;-------------------------------------------------------------------------;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< ; <<<<<<_5_ <<<OVER3: cmp al,'5' ; <<<<<<<<<<<<<<<<<<<
24
jne OVER4mov bp,OFFSET FivePressedcall DispMess
OVER4:JMP LOP ; REPEAT UNTIL SICK OF IT!;-------------------------------------------------------------------------;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< exit: mov bp, OFFSET XPRESSED
call DispMess
call Delaycall Delaycall Delay
mov ax,4C00h ; return to DOS <<<<<<<<< EXIT <<<<<call blank ; <<<<<<<<<<<<<<<<<<<<int 21h ; exit programret ;
;------------------------------------------------------------
;<<<<<<<<<<<<|===================|<<<<<<<<<<<<<<<<<<<<<<<<<<< ;============| CALLED PROCEDURES |=========================== ;>>>>>>>>>>>>|===================|>>>>>>>>>>>>>>>>>>>>>>>>>>> ;============================================================ ; MENU SCREEN PROCEDURE <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
DISPLAY_MENU: push bp
call bg ; writes background box to screencall tb ; writes top and bottom border to box call bs ; paints sides of box
;---------------------------------------------------------- mov LineNo,10 ;print menumov ColNo,25MOV COLOUR,26
;------<<<<<<<<<<<<<<<< DISPLAY MENU TEXT >>>>>>>>>>>>>>>>- mov bp,OFFSET Text2 ;ES:BP points to message call Disp ;displays intro message
;---------------------------------------------------------- inc LineNomov bp,OFFSET Text3 ;ES:BP points to message call Disp ;displays intro message
;----------------------------------------------------------
25
inc LineNomov bp,OFFSET Text6 ;ES:BP points to message call Disp ;displays intro message
;---------------------------------------------------------- inc LineNomov bp,OFFSET Text5 ;ES:BP points to message call Disp ;displays intro message
;---------------------------------------------------------- inc LineNomov bp,OFFSET Text7 ;ES:BP points to message call Disp ;displays intro message
;---------------------------------------------------------- mov LineNo,15mov bp,OFFSET Text ;displays intro messagecall Disp pop bxret
;---------------------------------------------------------- ;========================================================== ; SCR BLANK PROCEDURE <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<;========================================================== blank_scr:
push axpush bxpush cxpush dxCALL BLANKpop dxpop cxpop bxpop axret
;----------------------------------------------------------
;============================== paints BOX bg: mov cx,8
mov LineNo,9mov bp,OFFSET Text4 ; ES:BP points to message
mov ColNo,25MOV COLOUR,26
again: push cx
26
call disppop cx
inc LineNoloop again
ret;============================== paints BOX Top and bottom TB: mov cx,2
mov LineNo,8mov bp,OFFSET Box1 ; ES:BP points to message mov ColNo,25MOV COLOUR,15
B2: push cxcall disppop cx
add LineNo,8loop B2
ret ;--------------------------------------------------------------;============================== paints BOX sides BS: mov cx,9
mov LineNo,8mov bp,OFFSET Box2 ; ES:BP points to message MOV COLOUR,15
B3: push cxmov ColNo,24 ; do the left side call dis2
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 bxpush cxpush dxmov ah,13h ; function 13 - write string
27
mov al,01h ; attrib in bl,move cursor xor bh,bh ; video page 0
mov bl,colour ; attribute 4 - magentamov cx,30 ; length of string
mov dh,LineNo ; row to put stringmov dl,ColNo ; column to put string
int 10h ; call BIOS service;--------------------------------------------------------------
pop dxpop cxpop bxpop axret ; end proc
;------------------------------------------------------------------;--------------------------------------------------------------; procedure to display sides of box;--------------------------------------------------------------Dis2: push ax
push bxpush cxpush dxmov ah,13h ; function 13 - write stringmov al,01h ; attrib in bl,move cursor xor bh,bh ; video page 0
mov bl,colour ; attribute 4 - magentamov cx,1 ; length of string
mov dh,LineNo ; row to put stringmov dl,ColNo ; column to put string
int 10h ; call BIOS servicepop dxpop cxpop bxpop ax
ret ; end proc;------------------------------------------------------------------;--------------------------------------------------------------;--------------------------------------------------------------; displays a string on the screen not using ints;--------------------------------------------------------------
28
;PUSH AND POP REGISTERS WHEN USING THIS PROCEDURE;--------------------------------------------------------------put_str: ; display string terminated by 0
; whose address is in axpush axpush bxpush cxpush dx ; save registers
mov ax, @datamov ds, axmov ax, OFFSET buffer;Test1
mov bx, ax ; store address in bxmov al, byte ptr [bx] ;
put_loop: cmp al, 0 ; al == 0 ?je put_fin ; while al != 0call putchar ; display characterinc bx ; bx = bx + 1mov al, byte ptr [bx] ; jmp put_loop ; repeat loop test
put_fin: pop dxpop cxpop bxpop ax ; restore registersret
;==============================================================
DispMess: push axpush bxpush cxpush dxmov ah,13h ; function 13 - write stringmov al,01h ; attrib in bl,move cursor xor bh,bh ; video page 0
mov bl,colour ; attribute 4 - magentamov cx,24 ; length of string
mov dh,23 ; row to put stringmov dl,20 ; column to put string
int 10h ; call BIOS service;--------------------------------------------------------------
29
pop dxpop cxpop bxpop axret ; end proc
;--------------------------------------------------------------;--------------------------------------------------------------;--------------------------------------------------------------;--------------------------------------------------------------end START_MAIN ; end prog;--------------------------------------------------------------;--------------------------------------------------------------;--------------------------------------------------------------
Exercise b
; -------------------------; IO library; -------------------------
PUBLIC putchar,getchar,getc,blank,cursor,cursor2PUBLIC putstring,getstring,newline,puts,delay,get_str
.MODEL SMALL
.DATAsub_tot DW 0 ;intermediate valueflag DB 0 ;general purpose flagLineNo db ?
; NEW <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<;.CODE; -----------------------------------------------------------------------delay: push ax
push bxpush cxpush dx ; creates 1 second delay mov cx,800
delay0: push cx mov cx, 0ffffh
30
delay1: loop delay1 pop cx loop delay0 pop dxpop cxpop bxpop ax
ret ;end proc;--------------------------------------------------------------putchar: push ax ;preserve registers used
push dxmov dl, al ;DOS routine requires char in DLmov ah, 02h ;set DOS function call numberint 21h ;call DOS functionpop dxpop ax
ret ; -----------------------------------------------------------------------getchar: mov ah, 0Ch ;set DOS function call numbers
mov al, 01hint 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 charcmp al, 0je putstring2 ; if end of string exitcall putchar ; else print char
inc bx ; increment string pointerjmp putstring1 ; repeat loop
putstring2: pop bxpop ax ; restore registers
ret; -------------------------------------------------------------getstring: push ax
push bx ; preserve registers
getstring1: call getchar ; get a charactercmp al, 0Dh ; if carriage-returnje getstring2 ; exit
31
mov DS:[bx], al ; save char in string bufferinc bx ; adjust string pointerjmp getstring1 ; repeat loop
getstring2: mov BYTE PTR DS:[bx], 0 ; add string terminatorpop bxpop axret
; ---------------------------------------------------------------puts: ; display a string terminated by $
; ax contains address of stringpush axpush bxpush cxpush dx ;Save register values
mov dx, axmov ah, 9int 21h ; call ms-dos to output string
pop dxpop cxpop bxpop ax ; Restore register valuesret
;--------------------------------------------------------------newline: push ax
mov al, 10call putcharmov al, 13call putchar
pop axret
; -------------------------------------------------------------getc: ; read character into al
push bxpush cxpush dx ;Save register valuesmov ah, 01h ; 07h DOES NOT ECHO KEYBOARD int 21h pop dxpop cxpop bx ; Restore register values
32
ret;-------------------------------------------------------------- blank: ;blanks screen
push axpush bxpush cxpush 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 dxpop cxpop dxpop ax
ret; -------------------------------------------------------------cursor:
push bxpush ax ;save these registers in case the calling
;program needs them xor bh,bh
mov ah,02h int 10h ;cursor move interrupt
pop axpop bx
retcursor2:
push bxpush ax ;save these registers in case the calling
;program needs them
33
xor bh,bh
mov ah,03h int 10h ;cursor move interrupt
pop axpop bx
ret
; -------------------------------------------------------------get_str: ; read string terminated by keyboard CR into array
; whose address is in ax. Terminate it with 0.
push bxpush bxpush cx ; save registers
mov bx, ax
call getc ; read first charactermov 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 + 1call getc ; read next charactermov byte ptr [bx], al ; In C: str[i] = aljmp get_loop ; repeat loop test
get_fin: mov byte ptr [bx], 0 ; terminate string with 0
pop dxpop cxpop bx ; restore registersret
; -------------------------------------------------------------
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
34
4. MODIFY THE OPTIONS TO DO OTHER TASKS, NOT JUST PRINTING A MESSAGE5. 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 0Dhlf equ 0Ahnew_line equ 0Dh,0Ah, '$'mess0 db 'calculation of ax + b = 0', new_linemess1 db 'enter a (-32768..32767)!', new_linemess2 db lf, cr, 'enter b (-32768..32767)!', new_linemess3 db cr, lf, cr, lf, 'data:', '$'mess4 db cr, lf, ' a = ', '$'mess5 db cr, lf, ' b = ', '$'mess6 db cr, lf, 'result: ', cr, lf, ' x = ', '$'mess7 db cr, lf, cr, lf, 'no solution!', new_linemess8 db cr, lf, cr, lf, 'infinite number of solutions!', new_lineerror db cr, lf, 'the number is out of range!', new_linetwice_nl db new_line, new_linemake_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'
35
;******************************************************************* 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: 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.
36
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 dxnot_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.
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_progno_solution: lea dx, mess7 call puts
37
jmp end_proginfinite: lea dx, mess8 call putsend_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 ; (-) / (-) = (+) ; (+) / (-) = (-) 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 '-'
38
pop dxchecked:
; 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_fractiondone: pop dx pop cx retprint_float endp
;***************************************************************
; prints dx as fraction of division by bx. ; dx - remainder. ; bx - divider. ; cx - maximum number of digits after the dot. print_fraction proc near push ax push dxnext_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
39
cmp ax, 0 jns not_sig1 not dxnot_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 dxnot_sig2: add dl, 30h ; convert to ascii code. call write_char ; print dl. pop dx
jmp next_fractionend_rem: pop dx pop ax retprint_fraction endp
;***************************************************************
; this procedure prints number in ax, ; 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:
40
cmp ax, 0 jns positive neg ax
mov dl, '-' call write_charpositive: call print_numxprinted: pop ax pop dx retprint_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.
; 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
41
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:
pop dx pop cx pop bx retprint_numx endp
;***************************************************************
; displays the message (dx-address) puts proc near push ax mov ah, 09h int 21h pop ax retputs endp
42
;*******************************************************************
; reads char from the keyboard into al ; (modifies ax!!!) read_char proc near mov ah, 01h int 21h retread_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, '-' 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
43
; 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 cxnot_minus:
pop ax pop dx retscan_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 retwrite_char endp
;***************************************************************
cseg ends end start
44
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