;FILENAME: UNIT16.TXT ; ; ASSEMBLY LANGUAGE COURSE, UNIT 16 ; By Don Stoner Revision: 2008.07.20 ; ; This program will print a 4-digit ; hex number that tells you the segment ; address of the memory location where ; DOS loaded the program. The CS ; register holds this number. The first ; 256 bytes, following that loaction, ; are called the Program Segment Prefix ; (PSP). The PSP is used by DOS to hold ; various kinds of information. ; ; One of the things which can be found ; in the PSP is the "command tail" ; comprising anything which you might ; type following the "TEST" required to ; run this program. That character ; string begins at 81h (with the space ; following the "TEST") and is ; terminated by the final C.R. ; Location 80h holds the length of the ; command tail, not counting the C.R. ; ORG 100h ; Code Starts at 100h ; ; Your code starts here (100h) right ; after the 256-byte (100h) PSP. ; ; First, we will print the segment ; address where our program got loaded: ; MOV AX,CS ;get CS CALL AXOUT ;and print it ; ; Since the segment address in CS tells ; us on which 16-byte boundary of the ; memory DOS loaded our program, we ; would need to multiply this number by ; 16 (or just append a hex 0 on the ; right) if we wanted to know where our ; code really got loaded. ; ; DOS will always load our program ; into exactly the same location. On a ; different computer, or one the same ; computer running a different version ; of DOS, this program would probably ; always get loaded in some other part ; of memory. ; ; Next we will print the command tail: ; MOV SI,81h ;Cue SI to the ;command tail LOOP_HERE: LODSB ;get a character CMP AL,13 ;is it the final ;C.R.? ;If it is, JZ END_OF_STRING ;Then exit CALL ASCOUT ;Else print it JMP LOOP_HERE ;and loop back ;to get the next END_OF_STRING: ; ; Finally, we return to DOS: ; INT 20h ;-------------------------------------- ; I/O Subroutines: ; ; These subroutines are very much like ; the ones we have used before, except ; that some code has been saved by ; leaving off the final CALL and RET ; at their ends, and just letting the ; program drop through into the ; last subroutine it normally would ; have called. That subroutine's RET ; then acts as the final return to the ; main program. Any of the four level ; of this stack can be called as a ; stand-alone routine. ; AXOUT: PUSH AX MOV AL,AH ;print AX CALL ALOUT POP AX ;instead of calling ; ;ALOUT a 2nd time, we ; ;just drop into it ALOUT: PUSH AX SHR AL,4 ;Print AL CALL LSNOUT POP AX ;instead of calling ; ;LSNOUT a 2nd time, ; ;we just drop into it LSNOUT: AND AL,0FH OR AL,30H CMP AL,3AH ;LSN to ASCII JC ASCOUT ADD AL,41H-3AH ; ;instead of calling ; ;ASCOUT. we just drop ; ;into it ; ASCOUT: MOV AH,0EH ;ASCII out, TTY mode MOV BH,0 ;Page MOV BL,6 ;Graphics color INT 10H ;BIOS call RET