; Program to print out the next 10 numbers after a number. ; Written in x86 Assembly Language. Compiled with A86 v3.22, 1990 ; check out my registers - make sure that nothing screws up by overwriting ; something. Make sure that you know what variable is in each register all ; the time. ; SI = copy of message pointer for manipulating ; DX = message pointer: initally it has length of line, etc as first two ; bytes. We then make it just point to message start. ; The DX pointer initally has output string, then it gets the numeric ; input (with 2 leader characters). We overwrite the numeric input with ; the numbers that we want (since we are not doing any other I/O). ; CL = string length, CH = used in CHECK9 subroutine as temporary stringlen ; BH = used as a flag in calling ROLLOVER9 ; BL = file handle ; AH = interrupts, passing values to subroutines, scratch register ; AL = loop counter -- GETS OVERWRITTEN BY INT 21 !! ; note: the number is stored as a character, never converted to binary. ; 1: print message MOV DX,MYTEXT ; DS:DX message pointer MOV CX,TXT_SIZE ; CX number of bytes to write MOV BX,1 CALL MSG_OUT ; WHAT IS INT 33 ??? mouse or DOS ??? ; 2: get input MOV AH,0A INT 21H ; 3: set up variables MOV SI,DX ; store pointer in SI where it can be manipulated MOV CH,0 ; zero out CH MOV CL,B[SI+1] ; put string length into CL MOV AL,0 ; AL will be the loop counter INC SI ; increment pointer twice INC SI MOV DX,SI ; now DX (and SI) pointer actually points to start of string. ADD SI,CX DEC SI ; now SI points to the last digit ; 4: main loop start MAIN_LOOP: INC AL CMP AL,10 ; do loop 10 times JA EXIT ; safer than just exiting when AL=10 ; -- any big number will exit MOV CH,CL ; use CH as temporary length counter CALL CHECK9 ; do increment and check for 9 rollovers CMP BH,1 JNE CONT1 CALL ROLLOVER9 CONT1: MOV BH,0 ; set BH back to zero MOV CH,0 ; zero out CH (so INT 21 doesn't thing string is huge MOV AH,13 ;print string out again, but first print a CRLF CALL STD_OUT MOV AH,10 CALL STD_OUT CALL MSG_OUT JMP MAIN_LOOP EXIT: ;MOV AX,04C00 ; sucessful program termination ;INT 33 ; back to DOS RET ; Return to DOS ;==================== SUBROUTINES ======================== CHECK9 PROC MOV AH,[SI] ; put byte in AH CMP AH,39H ; is this digit 9 ? JE CONT2 ; YES -> got to cont2 INC AH ; increment MOV [SI],AH ; put back into data string RET CONT2: MOV B[SI],30H ; set digit back to zero CMP CH,1 ; is string length now 1 ? JNE CONT3 ; (actually see if it is 1 or less) MOV BH,1 ; flag to insert a new digit RET CONT3: DEC CH ; now check previous digit DEC SI CALL CHECK9 INC SI INC CH RET CHECK9 ENDP ROLLOVER9 PROC ;use real string length and move them all back one! MOV CH,CL ; make copy of string length LOOP2: MOV AH,[SI] ; copy digit to AH MOV B[SI+1],AH ; move to next position DEC CH ; decrement pointers to previous digit DEC SI CMP CH,1 ; are we at first digit yet? JG LOOP2 MOV B[SI],31H ; insert a 1 INC CL ; real string length is 1 digit longer MOV CH,0 MOV SI,DX ; fix up SI again ADD SI,CX DEC SI RET ROLOVER9 ENDP MSG_OUT PROC ; DX has message, null terminated, CX=string length PUSH AX ; BX=file handle (1=console) ; none of these are ever changed (except for AX) MOV AH,040H ; INT 21 code for write to device BX INT 21H POP AX RET MSG_OUT ENDP STD_OUT PROC ; AH has character to output PUSH AX,DX ; Save registers MOV DL,AH ; In DL for DOS call MOV AH,2 ; Standard output INT 21H ; DOS call POP DX,AX ; Restore registers RET ; Return STD_OUT ENDP MYTEXT: DB 'Enter a number (integer) ',0 TXT_SIZE EQU $ - MYTEXT