¡¡¡¡
¡¡¡¡;*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
¡¡¡¡¡¡¡¡;eg9-21.asm
¡¡¡¡¡¡¡¡;Purpose: print an ASCII file which is supposed
¡¡¡¡¡¡¡¡; to be already loaded into file_buffer
¡¡¡¡¡¡¡¡;* * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* * *
¡¡¡¡ ¡¡¡¡¡¡ .model small
¡¡¡¡;---------------------------------------------------------------
¡¡¡¡¡¡¡¡¡¡¡¡.stack
¡¡¡¡;---------------------------------------------------------------
¡¡¡¡¡¡¡¡¡¡¡¡.data
¡¡¡¡count ¡¡¡¡¡¡dw 0 ¡¡¡¡¡¡¡¡¡¡¡¡¡¡;count char num in a line
¡¡¡¡file_buffer db 'Hello',09h ¡¡¡¡;file buffer
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡db 'Hello',0dh, 0ah
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡db 'Hello world',1ah
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡db 487 dup(' ')
¡¡¡¡prt_buffer¡¡db 82 dup(' ') ¡¡¡¡;print buffer
¡¡¡¡;---------------------------------------------------------------
¡¡¡¡¡¡¡¡¡¡¡¡.code
¡¡¡¡; Main program
¡¡¡¡main ¡¡proc ¡¡far
¡¡¡¡start:
¡¡¡¡¡¡¡¡¡¡ mov ¡¡ ax, @data ¡¡¡¡¡¡ ;ds<=data segment
¡¡¡¡¡¡¡¡¡¡ mov¡¡¡¡ds, ax
¡¡¡¡¡¡¡¡ ¡¡mov¡¡¡¡ax, @data ¡¡¡¡¡¡ ;es<=data segment
¡¡¡¡¡¡¡¡¡¡ mov ¡¡ es, ax
¡¡¡¡¡¡¡¡¡¡ call¡¡ prt_file¡¡¡¡¡¡¡¡ ;print the
ASCII file
¡¡¡¡¡¡¡¡¡¡ mov ¡¡ ax£¬4c00h
¡¡¡¡¡¡¡¡¡¡ int¡¡¡¡21h
¡¡¡¡main¡¡ endp
¡¡¡¡;---------------------------------------------------------------
¡¡ ; Procedure prt_file
¡¡¡¡; Purpose: print an ASCII file in file_buffer
¡¡ ;---------------------------------------------------------------
¡¡¡¡prt_file proc near
¡¡¡¡;initialize
¡¡¡¡¡¡¡¡¡¡ cld¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡ ;set left to right
¡¡¡¡¡¡¡¡¡¡ lea ¡¡si, file_buffer ¡¡¡¡;si<=address of file_buffer
¡¡¡¡load_di:
¡¡¡¡¡¡¡¡¡¡ lea¡¡ di, prt_buffer¡¡¡¡¡¡;di<=address of prt_buffer
¡¡¡¡¡¡¡¡¡¡ mov ¡¡count, 0 ¡¡¡¡¡¡¡¡¡¡ ;clear count
¡¡¡¡load_dx:
¡¡¡¡¡¡¡¡¡¡ lea ¡¡dx, file_buffer+512 ;dx<=end of file_buffer
¡¡¡¡¡¡¡¡¡¡ cmp ¡¡si, dx¡¡¡¡¡¡¡¡¡¡¡¡¡¡;end of file_buffer?
¡¡¡¡¡¡¡¡¡¡ je ¡¡ prt_lastline ¡¡¡¡¡¡ ;print the last line
¡¡¡¡¡¡¡¡¡¡ mov ¡¡bx, count¡¡¡¡¡¡¡¡¡¡ ;bx<=count
¡¡¡¡¡¡¡¡¡¡ cmp¡¡ bx, 80 ¡¡¡¡¡¡¡¡¡¡¡¡ ;end of a print line?
¡¡¡¡¡¡¡¡¡¡ jb¡¡¡¡not_endl
¡¡¡¡;dispose when reach end of line
¡¡¡¡¡¡¡¡¡¡ mov ¡¡word ptr[di+bx], 0d0ah ¡¡¡¡;insert CR/LF
¡¡¡¡¡¡¡¡¡¡ add ¡¡count, 2 ¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡;reset count
¡¡¡¡¡¡¡¡¡¡ call¡¡prt_line ¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡;print the line
¡¡¡¡¡¡¡¡¡¡ mov¡¡ count, 0 ¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡;clear count
¡¡¡¡¡¡¡¡¡¡ mov ¡¡bx, 0
¡¡¡¡not_endl:
¡¡¡¡¡¡¡¡¡¡ lodsb ¡¡¡¡¡¡ ¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡ ;al<=[si], increase si
¡¡¡¡¡¡¡¡¡¡ mov [di+bx],¡¡al ¡¡¡¡¡¡¡¡¡¡¡¡ ;copy char to prt_buffer
¡¡¡¡¡¡¡¡¡¡ inc¡¡¡¡¡¡ ¡¡¡¡bx¡¡¡¡¡¡¡¡¡¡¡¡¡¡;reset bx(count)
¡¡¡¡¡¡¡¡¡¡ cmp¡¡¡¡¡¡ ¡¡¡¡al, 1ah¡¡¡¡¡¡¡¡ ;end of file?
¡¡¡¡¡¡¡¡¡¡ je¡¡¡¡¡¡¡¡¡¡¡¡prt_lastline
¡¡¡¡¡¡¡¡¡¡ cmp¡¡¡¡¡¡¡¡¡¡ al, 0ah ¡¡¡¡¡¡¡¡;end of line?
¡¡¡¡¡¡¡¡¡¡ jne¡¡¡¡¡¡¡¡¡¡ handle_tab ¡¡¡¡ ;handle Tab character
¡¡¡¡¡¡¡¡¡¡ call¡¡¡¡¡¡¡¡¡¡prt_line ¡¡¡¡¡¡ ;print the line
¡¡¡¡¡¡¡¡¡¡ jmp¡¡¡¡¡¡¡¡¡¡ load_di
¡¡¡¡;dispose if meeting Tab character
¡¡¡¡handle_tab:
¡¡¡¡¡¡¡¡¡¡¡¡¡¡cmp ¡¡¡¡¡¡¡¡al, 09h ¡¡¡¡¡¡¡¡;Tab char?
¡¡¡¡¡¡¡¡¡¡¡¡¡¡jne ¡¡¡¡¡¡¡¡not_tab
¡¡¡¡¡¡¡¡¡¡¡¡¡¡dec ¡¡¡¡¡¡¡¡bx
¡¡¡¡¡¡¡¡¡¡¡¡¡¡mov ¡¡¡¡¡¡¡¡byte ptr[di+bx], 20h ¡¡¡¡;Tab->blank
¡¡¡¡;get the correct position of the character right after Tab
¡¡¡¡¡¡¡¡¡¡¡¡¡¡and ¡¡¡¡¡¡¡¡bx, 0fff8h¡¡¡¡¡¡;clear rightmost 3 bits
¡¡¡¡¡¡¡¡¡¡¡¡¡¡add ¡¡¡¡¡¡¡¡bx, 8¡¡¡¡¡¡¡¡¡¡ ; & add 8-->Tab stop
¡¡¡¡not_tab:
¡¡¡¡¡¡¡¡¡¡¡¡¡¡mov ¡¡¡¡¡¡¡¡count, bx ¡¡¡¡¡¡;refresh count
¡¡¡¡¡¡¡¡¡¡¡¡¡¡jmp ¡¡¡¡¡¡¡¡load_dx
¡¡¡¡;print the last line
¡¡¡¡prt_lastline:
¡¡¡¡¡¡¡¡¡¡¡¡¡¡mov ¡¡¡¡¡¡¡¡bx, count ¡¡¡¡¡¡;refresh bx
¡¡¡¡¡¡¡¡¡¡¡¡¡¡mov ¡¡¡¡¡¡¡¡byte ptr[di+bx], 0ch ¡¡;insert page break
¡¡¡¡¡¡¡¡¡¡¡¡¡¡call ¡¡¡¡¡¡ prt_line ¡¡¡¡¡¡ ;print the line
¡¡¡¡¡¡¡¡¡¡¡¡¡¡ret
¡¡¡¡prt_file¡¡endp
¡¡¡¡;----------------------------------------------------------------
¡¡¡¡; Procedure prt_line
¡¡¡¡; Purpose: print a line in prt_buffer
¡¡¡¡;----------------------------------------------------------------
¡¡¡¡prt_line proc near
¡¡¡¡;initialize
¡¡¡¡¡¡¡¡¡¡¡¡¡¡mov ¡¡¡¡¡¡¡¡cx, count ¡¡¡¡¡¡;cx<=length of line
¡¡¡¡¡¡¡¡¡¡¡¡¡¡inc ¡¡¡¡¡¡¡¡cx
¡¡¡¡¡¡¡¡¡¡¡¡¡¡mov ¡¡¡¡¡¡¡¡bx, 0 ¡¡¡¡¡¡¡¡¡¡;bx: pointer in prt_buffer
¡¡¡¡prt_char:
¡¡¡¡¡¡¡¡¡¡¡¡¡¡mov ¡¡¡¡¡¡¡¡ah, 5 ¡¡¡¡¡¡¡¡¡¡;to send print request
¡¡¡¡¡¡¡¡¡¡¡¡¡¡mov ¡¡¡¡¡¡¡¡dl, prt_buffer[bx] ¡¡;dl<=character to be printed
¡¡¡¡¡¡¡¡¡¡¡¡¡¡int ¡¡¡¡¡¡¡¡21h ¡¡¡¡¡¡¡¡¡¡¡¡;call DOS
¡¡¡¡¡¡¡¡¡¡¡¡¡¡inc ¡¡¡¡¡¡¡¡bx ¡¡¡¡¡¡¡¡¡¡¡¡ ;move pointer
¡¡¡¡¡¡¡¡¡¡¡¡¡¡loop ¡¡¡¡¡¡ prt_char ¡¡¡¡¡¡ ;print another character
¡¡¡¡;clear prt_buffer
¡¡¡¡¡¡¡¡¡¡¡¡¡¡mov ¡¡¡¡¡¡¡¡ax, 2020h ¡¡¡¡¡¡;to fill with blank
¡¡¡¡¡¡¡¡¡¡¡¡¡¡mov ¡¡¡¡¡¡¡¡cx, 41 ¡¡¡¡¡¡¡¡ ;cx<=buffer size
¡¡¡¡¡¡¡¡¡¡¡¡¡¡lea ¡¡¡¡¡¡¡¡di, prt_buffer¡¡;di<=address of prt_buffer
¡¡¡¡¡¡¡¡¡¡¡¡¡¡rep ¡¡¡¡¡¡¡¡stosw¡¡¡¡¡¡¡¡¡¡ ;fill
¡¡¡¡¡¡¡¡¡¡¡¡¡¡ret ¡¡¡¡¡¡¡¡prt_line¡¡endp
¡¡ ;-----------------------------------------------------------------
¡¡¡¡¡¡¡¡¡¡end ¡¡¡¡start