; PRINT.ASM ; This program demonstrates an unconventional way of saving registers ; and passing arguments to subroutines in 8086 assembly language. ; The DATA in this program gets embedded into the code, ; which makes debugging a little bit tricky. ; This source code was compiled with TASM 3.2 with no errors. CODE SEGMENT ASSUME CS:CODE, DS:CODE, ES:CODE, SS:CODE ORG 0100h ENTRY: JMP MAIN ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; SaveRegs ;; ;; When this function returns, it leaves ;; 16 bytes (AX,BX,CX,DX,SI,DI,ES,DS) on the ;; stack, so don't forget to call ;; RestoreRegs soon afterwards! ;; ;; Destroys: BP SaveRegs: POP BP ; FROM address -> BP PUSH AX PUSH BX PUSH CX PUSH DX PUSH SI PUSH DI PUSH ES PUSH DS PUSH BP ; STACK <- FROM address RET ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; RestoreRegs ;; ;; This will remove 16 bytes from the stack ;; and restore the value of AX, BX, CX, DX, ;; SI, DI, ES, and DS. ;; ;; Destroys: BP RestoreRegs: POP BP ; FROM address -> BP POP DS POP ES POP DI POP SI POP DX POP CX POP BX POP AX PUSH BP ; STACK <- FROM address RET ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; CLRSCR ;; This function clears the screen using ;; color code passed in register BH. ;; Example: Calling CLRSCR with BH=1Eh will ;; result in a solid blue background. Text ;; printed will appear in bright yellow. ;; ;; Destroys: BP CLRSCR: CALL SaveRegs MOV AX,0003h INT 10h ; Change to 80x25 color text mode MOV AX,061Ah MOV DX,1A50h XOR CX,CX INT 10h ; Clears the screen using color code in BH MOV AX,0200h XOR BX,BX MOV DX,BX INT 10h ; Move cursor to top of screen CALL RestoreRegs RET ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; DOS_PRINT ;; This function prints a string using DOS ;; INT 21 AH=09. The string must end with ;; a dollar sign. Destroys: AX, DX, SI, flags ;; ;; Usage: CALL DOS_PRINT ;; DB "STRING TO PRINT$" ;; DOS_PRINT: POP SI ; FROM address -> SI MOV DX,SI ; Save string's address for DOS interrupt later CLD ; Clear Direction flag for LODSB instruction NextChr: LODSB ; Get first byte of string -> AL CMP AL,"$" ; Count characters until the "$" sign JNE NextChr PUSH SI ; STACK <- FROM address + STRING Length MOV AX,0900h INT 21h ; PRINT STRING TO STDOUT RET ; Go back and skip string ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; EXIT EXIT MACRO INT 20h ; Exit to DOS ENDM ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; PRINT PRINT MACRO STRING CALL DOS_PRINT DB STRING, 10, 13, 36 ENDM ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; PRINT COLOR MACRO COLORCODE MOV BH,COLORCODE ENDM CLS MACRO CALL CLRSCR ENDM ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; GETKEY GETKEY MACRO XOR AX,AX INT 16h ENDM ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; MAIN MAIN: ; With the help of macros this code looks like QBASIC: COLOR 1Fh CLS PRINT "Hello World!!" PRINT "Hey!!" PRINT "PRESS ANY KEY TO EXIT..." GETKEY COLOR 07h CLS EXIT CODE ENDS END ENTRY