Discovery Zone: Keeping Knowledge Free!
Search:
Keywords:
In Association with Amazon.com
Another great reference
cover
Assembly Language Programs and Organizations of the IBM PC

ASSEMBLY PROGRAMMING AND OS DESIGN


2. Intro to Assembly
2.1 Data Types
2.2 Registers
2.3 DOS Int Calls
2.4 Basic Commands
2.4.1 DOS Hello World
2.5 BIOS Int Calls
2.5.1 BIOS Hello World
2.6 String Routines

<HOME>

 

 

 

 

 

 

 

 

Another great reference
cover 80X86 IBM PC and Compatible Computers: Assembly Language, Design and Interfacing Vol. I and II

 

 

 

 

 

 

 

 

 

 

 

 

 

Need a good reference?
cover
Assembly Language Step-by-Step: Programming with DOS and Linux, 2nd Edition
CH2.6 String Routines

<HOME><TOC><PREV><UP><NEXT>

You've used DOS to display stuff.  You've used BIOS as well.  Now it's time to do everything without any help.  The title of this section may be string routines, but by the time you finish this section, you will have written a fully functional, 16 BIT terminal output library.

TERM_X        db     0
TERM_Y        db     0
TEXT_PROPERTY db     1fh
TERM_CURSOR   db     "_"
CURSOR_MEM    dw     0

;====================================
; cls
;====================================

_CLS:         push   CX
              push   GS
              push   BX
              mov    AX,0b800h
              mov    GS,AX
              mov    AL,0
              mov    AH,[TEXT_PROPERTY]
              mov    CX,3200
              mov    BX,0
.LOOP:        mov    [GS:BX],AX
              inc    BX
              inc    BX
              dec    CX
              jnz    .LOOP
              mov    [CURSOR_MEM],AX
              pop    BX
              pop    GS
              pop    CX
              ret

;====================================
; putc(ch) where BL contains ch
;====================================

_PUTC:        push   DX
              push   ES
              push   SI
              mov    AX,0b800h
              mov    ES,AX                ;set up screen segment
              mov    BH,[TEXT_PROPERTY]   ;load display property
              mov    SI,0                 ;screen address
              mov    AL,160               ;screen is 160 BYTES in width
              mul    byte [TERM_Y]        ;AX=160*TERM_Y
              mov    DL,[TERM_X]          ;DL=TERM_X
              movzx  DX,[TERM_X]          ;DX=DL
              shl    DX,1                 ;DX=DX*2 - 2 BYTES per char
              add    AX,DX                ;AX=AX+DX - offset in screen
              add    SI,AX
              mov    AL,[TERM_X]          ;AL=TERM_X for updating
              cmp    BL,13                ;process CR
              je     CARRIAGE_RETURN
              cmp    BL,10                ;ignore LF
              je     DONE2
              cmp    BL,0
              je     DRAW_CURSOR
              mov    [ES:SI],BX
              inc    SI
              inc    SI
              inc    AL
              cmp    AL,40
              jb     DRAW_CURSOR
CARRIAGE_RETURN:
              mov    BX,[CURSOR_MEM]      ;replace old cursor with mem
              mov    [ES:SI],BX
              xor    AL,AL
              inc    byte [TERM_Y]        ;adjust x and y to next line
              cmp    byte [TERM_Y],25
              jb     DRAW_CURSOR
              dec    byte [TERM_Y]
              mov    SI,160
              mov    DI,0
              mov    CX,24*160
              rep
              ES movsw
              mov    CX,160
              mov    AH,[TEXT_PROPERTY]
              mov    AL,0
              rep
              stosw 
DRAW_CURSOR:  mov    [TERM_X],AL          ;recompute address for cursor
              mov    SI,0                 ;screen address
              mov    AL,160               ;screen is 160 BYTES in width
              mul    byte [TERM_Y]        ;AX=160*TERM_Y
              mov    DL,[TERM_X]          ;DL=TERM_X
              movzx  DX,[TERM_X]          ;DX=DL
              shl    DX,1                 ;DX=DX*2 - 2 BYTES per char
              add    AX,DX                ;AX=AX+DX - offset in screen
              add    SI,AX
DONE1:        mov    AH,[TEXT_PROPERTY]
              mov    AL,[TERM_CURSOR]
              mov    BX,[ES:SI]
              mov    [CURSOR_MEM],BX
              mov    [ES:SI],AX
DONE2:        pop    SI
              pop    GS
              pop    DX
              ret

;====================================
; puts(string*) - where BX points to
; NULL terminated string
;====================================

_PUTS:        push   BX
              xor    AX,AX
              mov    SI,BX
.LOOP:        mov    BL,byte [SI]
              cmp    BL,0
              je     DONE_PUTS
              call  _PUTC
              inc    SI
              inc    AX
              jmp    .LOOP
DONE_PUTS:    pop    BX
              ret

;====================================
; puthex(hex) - where BL contains
; value to display in hex
;====================================

_PUTHEX:      push   BX
              push   CX
              shl    BX,4
              shr    BL,4
              cmp    BL,10
              jb     ITS_A_NUMBERL
              add    BL,7                 ;48+17=65 which is ASCII for 'A'
ITS_A_NUMBERL:
              add    BL,48
              mov    CL,BL
              shr    BX,4
              shr    BL,4
              cmp    BL,10
              jb     ITS_A_NUMBERH
              add    BL,7                 ;48+17=65 which is ASCII for 'A'
ITS_A_NUMBERH:
              add    BL,48
              call   _PUTC
              mov    BL,CL
              call   _PUTC
              pop    CX
              pop    BX
              ret

;=======================================
; set_term_xy(x,y) - where BH contains y
; coordinate and BL contains x
;=======================================

_SET_TERM_XY: push   BX
              push   DX
              push   ES
              push   SI
              mov    AX,0b800h
              mov    GS,AX                ;set up screen segment
              mov    SI,0                 ;screen address
              mov    AL,160               ;screen is 160 BYTES in width
              mul    byte [TERM_Y]        ;AX=160*TERM_Y
              mov    DL,[TERM_X]          ;DL=TERM_X
              movzx  DX,[TERM_X]          ;DX=DL
              shl    DX,1                 ;DX=DX*2 - 2 BYTES per char
              add    AX,DX                ;AX=AX+DX - offset in screen
              add    SI,AX
              mov    AX,[CURSOR_MEM]
              mov    [ES:SI],AX
              mov    [TERM_X],BX
              mov    BH,[TEXT_PROPERTY]   ;load display property
              mov    SI,0                 ;screen address
              mov    AL,160               ;screen is 160 BYTES in width
              mul    byte [TERM_Y]        ;AX=160*TERM_Y
              mov    DL,[TERM_X]          ;DL=TERM_X
              movzx  DX,[TERM_X]          ;DX=DL
              shl    DX,1                 ;DX=DX*2 - 2 BYTES per char
              add    AX,DX                ;AX=AX+DX - offset in screen
              add    SI,AX
              mov    AX,[ES:SI]
              mov    [CURSOR_MEM],AX
              mov    BL,[TERM_CURSOR]
              mov    [ES:SI],BX
              pop    SI
              pop    ES
              pop    DX
              pop    BX
              ret

;====================================
; set_text_property(pr) - where BL
; contains pr
;====================================

_SET_TEXT_PROPERTY:
              mov    [TEXT_PROPERTY],BL
              ret

<HOME><TOC><PREV><UP><NEXT>
 

www.cynergysoft.com

Email any questions to the author, Nathan Daniels.

Copyright © 2001