Creating an Interactive Guessing Game

Materials:
Working complete PC
Blank Diskette
Source Code Diskette (created in the Introduction to TASM module)
Student Diskette, "New Boot A Ver 2.0+"
Student CD-ROM, "QBOOT" (any version)
Objectives:
The student will become familiar with the Borland Turbo Assembly language compiler including:
designing a blank source code file,
building a source file in stages,
building a developer's batch file,
building internal procedures,
building a random number generator,
building an ASCII to binary converter,
building the object file,
building the executable.
Competency:
The student will learn how to design executable assembly lanugage programs and how to compile and link the source code text file into an executable. The student will become familiar with some basic compiler "dot" directives and some simple machine language instructions.

    Preparation

  1. The student will need a copy of Borland's Turbo Assembly Lanugage software, preferably version 5.0.

  2. After launching QBOOT by pressing [F8] say yes to all CONFIG.SYS prompts and all AUTOEXEC.BAT prompts except the last one to launch Windows 3.11.

  3. Change to the K: drive and insert the source code diskette created in the Introduction to TASM module. Copy BLANK.ASM from the diskette to the root of the K: drive and then run "edit blank.asm" All assembly language source files should have the file extention .ASM so that the compilers can easily recognize them.

  4. Procedures

  5. In EDIT's main field, the following source code should be present:

    .model tiny
    .stack 200h
    .data
    .code
    main proc
      mov ax, @data
      mov ds, ax
    terminate:
      mov ax, 4C00h
      int 21h
    main endp
    end main
    
  6. Press [Alt]+[F] to open the File menu and then press [A] to save the file with a new name. Name the file GUESS.ASM. Make the following changes:

    .model tiny
    .stack 200h
    .data
    titlemsg   db   "Guess the Number Version 1.0", 0Dh, 0Ah, '$'
    playmsg    db   "Play the game? (Y/N): $"
    promptmsg  db   0Dh, 0Ah, "Guess a number between 1 and 100 (Q=Quit): $"
    toohimsg   db   0Dh, 0Ah, "Too High!", 0Dh, 0Ah, '$'
    toolomsg   db   0Dh, 0Ah, "Too Low!", 0Dh, 0Ah, '$'
    gotitmsg   db   0Dh, 0Ah, "You got it!", 0Dh, 0Ah, '$'
    badinmsg   db   0Dh, 0Ah, "Entry must be number from 1-100 or Q!", 0Dh, 0Ah, '$'
    maxlen     db   4
    strlen     db   0
    inbuf      db   5 dup('$')
    randnum    db   0
    usernum    db   0
    placevals  db   1, 10, 100
    
    .code
    main proc
      mov ax, @data
      mov ds, ax
    start:  
      mov ah, 9
      mov dx, offset titlemsg
      int 21h
    again:  
      mov ah, 9
      mov dx, offset playmsg
      int 21h
      mov ah, 1     ;function 1: input one character and wait for it
      int 21h
      cmp al, 'y'   ;function 1 returns the char in AL
      je cont1
      cmp al, 'Y'   ;checking for either upper or lower case Y
      je cont1
      jmp terminate ;automatically quit with any other response
    cont1:
    ;generate random number here
    cont2:
    ;get a guess from the user here
    ;compare it with the random number here
    ;display correct response, if they guessed it then
    ;jump to "again" else jump to cont2
    terminate:
      mov ax, 4C00h             ;function 4C = quit program
      int 21h
    main endp
    end main
    

  7. Press [Alt]+[F] then [S] to save the changes. The highlighted lines are the ones that were added to the original BLANK.ASM. The first change creates the new variables and the second change starts creating the executable code. This is going to be a long project so it should be developed in stages starting with a few executable lines and then notes on what needs to be added later.

  8. At this point because there is going to be a lot of repitition of commands to copy the file to the floppy, then compile, link and execute it a batch file can be developed to do these things automatically:

    K:\>copy con dev.bat
    @echo off
    :repeat
    edit %1.asm
    choice /C:YN Continue
    if errorlevel 2 goto end
    copy %1.asm b:
    choice /C:YN Continue
    if errorlevel 2 goto end
    tasm /zi %1
    choice /C:YN Continue
    if errorlevel 2 goto end
    tlink /v %1
    choice /C:YN Execute
    if errorlevel 2 goto end
    %1
    choice /C:YN Continue
    if errorlevel 2 goto end
    goto repeat
    :end
    ^Z
      1 file(s) copied
    K:\>_
    
  9. Now copy dev.bat to the source code floppy then execute it like this:

    K:\>copy dev.bat b:
      1 file(s) copied
    K:\>dev guess
    
  10. This will launch EDIT and load the source file on screen. Exit EDIT and the prompt to continue will be displayed. Type [Y] and the file will be copied to the floppy followed by another prompt to continue:

    K:\>dev guess
    Continue[Y/N]?Y
      1 file(s) copied
    Continue[Y/N]?_
    
  11. Press [Y] and the batch file will execute the command to compile the source code file and follow this with another continue prompt:

    K:\>dev guess
    Continue[Y/N]?Y
      1 file(s) copied
    Continue[Y/N]?Y
    Turbo Assembler  Version 4.1  Copyright (c) 1988, 1996 Borland International
    Assembling file:   guess.ASM
    Error messages:    None
    Warning messages:  None
    Passes:            1
    Remaining memory:  335k
    Continue[Y/N]?_
    
  12. If the compiler reports no warnings or errors then press [Y] and it will then link the executable and follow this with an execute prompt:

    K:\>dev guess
    Continue[Y/N]?Y
      1 file(s) copied
    Continue[Y/N]?Y
    Turbo Assembler  Version 4.1  Copyright (c) 1988, 1996 Borland International
    Assembling file:   guess.ASM
    Error messages:    None
    Warning messages:  None
    Passes:            1
    Remaining memory:  335k
    Continue[Y/N]?Y
    Turbo Link  Version 7.1.30.1. Copyright (c) 1987, 1996 Borland International
    Execute[Y/N]?_
    
  13. This one is dangerous because the executable may have logic bugs that cause it to lock up the machine. In the future the DEV.BAT will be modified to allow us to either run the program that is being compiled and linked OR to send it to the Turbo Debugger. For now press [Y] and the program runs:

    K:\>dev guess
    Continue[Y/N]?Y
      1 file(s) copied
    Continue[Y/N]?Y
    Turbo Assembler  Version 4.1  Copyright (c) 1988, 1996 Borland International
    Assembling file:   guess.ASM
    Error messages:    None
    Warning messages:  None
    Passes:            1
    Remaining memory:  335k
    Continue[Y/N]?Y
    Turbo Link  Version 7.1.30.1. Copyright (c) 1987, 1996 Borland International
    Execute[Y/N]?Y
    Guess the Number Version 1.0
    Play the game? (Y/N): _
    
  14. Press [N] and the program should end and display the continue prompt again:

    K:\>dev guess
    Continue[Y/N]?Y
      1 file(s) copied
    Continue[Y/N]?Y
    Turbo Assembler  Version 4.1  Copyright (c) 1988, 1996 Borland International
    Assembling file:   guess.ASM
    Error messages:    None
    Warning messages:  None
    Passes:            1
    Remaining memory:  335k
    Continue[Y/N]?Y
    Turbo Link  Version 7.1.30.1. Copyright (c) 1987, 1996 Borland International
    Execute[Y/N]?Y
    Guess the Number Version 1.0
    Play the game? (Y/N): n
    Continue[Y/N]?_
    
  15. Pressing [Y] will loop the batch file back to the repeat label and open the source code in EDIT once again. Pressing [N] will quit the batch file and land at the command prompt again. Press [Y] to open the program in EDIT once again. Make the following changes:

    .model tiny
    .stack 200h
    .data
    titlemsg   db   "Guess the Number Version 1.0", 0Dh, 0Ah, '$'
    playmsg    db   "Play the game? (Y/N): $"
    promptmsg  db   0Dh, 0Ah, "Guess a number between 1 and 100 (Q=Quit): $"
    toohimsg   db   0Dh, 0Ah, "Too High!", 0Dh, 0Ah, '$'
    toolomsg   db   0Dh, 0Ah, "Too Low!", 0Dh, 0Ah, '$'
    gotitmsg   db   0Dh, 0Ah, "You got it!", 0Dh, 0Ah, '$'
    badinmsg   db   0Dh, 0Ah, "Entry must be number from 1-100 or Q!", 0Dh, 0Ah, '$'
    maxlen     db   4
    strlen     db   0
    inbuf      db   5 dup('$')
    randnum    db   0
    usernum    db   0
    placevals  db   1, 10, 100
    
    .code
    main proc
      mov ax, @data
      mov ds, ax
    start:  
      mov ah, 9
      mov dx, offset titlemsg
      int 21h
    again:  
      mov ah, 9
      mov dx, offset playmsg
      int 21h
      mov ah, 1     ;function 1: input one character and wait for it
      int 21h
      cmp al, 'y'   ;function 1 returns the char in AL
      je cont1
      cmp al, 'Y'   ;checking for either upper or lower case Y
      je cont1
      jmp terminate ;automatically quit with any other response
    cont1:
      call getrand  ;generate random number
    cont2:
    ;get a guess from the user here
    ;compare it with the random number here
    ;display correct response, if they guessed it then
    ;jump to "again" else jump to cont2
    terminate:
      mov ax, 4C00h             ;function 4C = quit program
      int 21h
    main endp
    
    getrand proc
      mov ah, 2Ch          ;function 2Ch: get system time from BIOS
      int 21h
    ;returns CH=hour, CL=minute, DH=second, DL=1/100ths of second
    ;it is the hundredths of a second that will help generate a nice random
    ;number since it is nearly impossible to predict
      xor ax, ax      ;AX=0
      add al, ch      ;add hour
      add al, cl      ;add minute
      add al, dh      ;add second to it
      add al, dl      ;add hundredths of second to it
    ;cl now holds hour + minute + second + hundredths of a second
      mov cx, 100     ;put the value 100 in ax for the DIV instruction
      div cl          ;the DIV instruction assumes that the named register or variable
                      ;will be divided into the number in the AL register
                      ;the result will be held in the AL and the remainder 
                      ;will be left in the AH
      inc ah          ;remainders of dividing anything by 100 will be zero to 99
                      ;add 1 and the possible numbers that will be left in AH are 1 to 100
      mov randnum, ah ;store the random number that can be from 1 to 100 into the variable
      ret             ;return from the procedure
    getrand endp
    end main
    
  16. Save the changes and exit EDIT. At the continue prompt enter a [Y] to copy the file to the floppy. Enter another [Y] to compile the source code. Be sure there are no errors. Press [Y] again to link the object file. Again be sure there are no errors. Press [N] when prompted to execute since the random value is stored in RAM and never displayed. Run dev guess again to open the source in EDIT again. Make the following changes:

    .model tiny
    .stack 200h
    .data
    titlemsg   db   "Guess the Number Version 1.0", 0Dh, 0Ah, '$'
    playmsg    db   "Play the game? (Y/N): $"
    promptmsg  db   0Dh, 0Ah, "Guess a number between 1 and 100 (Q=Quit): $"
    toohimsg   db   0Dh, 0Ah, "Too High!", 0Dh, 0Ah, '$'
    toolomsg   db   0Dh, 0Ah, "Too Low!", 0Dh, 0Ah, '$'
    gotitmsg   db   0Dh, 0Ah, "You got it!", 0Dh, 0Ah, '$'
    badinmsg   db   0Dh, 0Ah, "Entry must be number from 1-100 or Q!", 0Dh, 0Ah, '$'
    maxlen     db   4
    strlen     db   0
    inbuf      db   5 dup('$')
    randnum    db   0
    usernum    db   0
    placevals  db   1, 10, 100
    
    .code
    main proc
      mov ax, @data
      mov ds, ax
    start:  
      mov ah, 9
      mov dx, offset titlemsg
      int 21h
    again:  
      mov ah, 9
      mov dx, offset playmsg
      int 21h
      mov ah, 1     ;function 1: input one character and wait for it
      int 21h
      cmp al, 'y'   ;function 1 returns the char in AL
      je cont1
      cmp al, 'Y'   ;checking for either upper or lower case Y
      je cont1
      jmp terminate ;automatically quit with any other response
    cont1:
      call getrand  ;generate random number
    cont2:
      call getguess ;get the guess
      call asc2bin  ;convert it to binary
      jc cont2      ;if conversion fails asc2bin will display a msg and set the carry flag
    ;compare it with the random number here
    ;display correct response, if they guessed it then
    ;jump to "again" else jump to cont2
    terminate:
      mov ax, 4C00h             ;function 4C = quit program
      int 21h
    main endp
    getrand proc
      mov ah, 2Ch          ;function 2Ch: get system time from BIOS
      int 21h
    ;returns CH=hour, CL=minute, DH=second, DL=1/100ths of second
    ;it is the hundredths of a second that will help generate a nice random
    ;number since it is nearly impossible to predict
      xor ax, ax      ;AX=0
      add al, ch      ;add hour
      add al, cl      ;add minute
      add al, dh      ;add second to it
      add al, dl      ;add hundredths of second to it
    ;cl now holds hour + minute + second + hundredths of a second
      mov cx, 100     ;put the value 100 in ax for the DIV instruction
      div cl          ;the DIV instruction assumes that the named register or variable
                      ;will be divided into the number in the AL register
                      ;the result will be held in the AL and the remainder 
                      ;will be left in the AH
      inc ah          ;remainders of dividing anything by 100 will be zero to 99
                      ;add 1 and the possible numbers that will be left in AH are 1 to 100
      mov randnum, ah ;store the random number that can be from 1 to 100 into the variable
      ret             ;return from the procedure
    getrand endp
    
    getguess proc
      mov ah, 9
      mov dx, offset promptmsg
      int 21h
    
      mov ah, 0Ah
      mov dx, offset maxlen
      int 21h
    
      ret
    getguess endp
    asc2bin proc
      xor ax, ax        ;AX=0
      mov usernum, al   ;clear unser number
      xor si, si        ;SI=0
      xor cx, cx        ;CX=0  
      mov cl, strlen    ;get the size of the string that the user entered
      mov bx, offset strlen     ;place offset of variable into BX
      mov di, offset placevals  ;place offset of place values into DI
    a2b1:
      xor dx, dx        ;DX=0
      mov si, cx        ;place offset of digit in buffer into SI
      mov dl, [bx + si] ;place ASCII digit into DL
      sub dl, 30h       ;subtract 30h leaving the binary equivalent of the digit
      mov al, [di]      ;get place value into AL
      mul dl            ;multiply dl x al result in AX
      add usernum, al   ;move the value into variable
      inc di            ;point to next place value
      loop  a2b1        ;dec 1 from cx, if cx=0 fall out of loop otherwize jmp to label
      mov al, usernum   ;retrieve usernum
      cmp al, 100       ;is it larger than 100?
      ja a2b2           ;yes jump to the error handler, otherwise ...
      clc               ;clear the carry flag,
      jmp a2bexit       ;and exit the proc
    a2b2:
      mov ah, 9
      mov dx, offset badinmsg
      int 21h
      stc               ;show error message and set the carry flag
    a2bexit:
      ret
    asc2bin endp
    
    end main
    
  17. Save these changes and exit EDIT. Press [Y] to continue which copies the file to the diskette, the next [Y] compiles, check for error messages. The next [Y] links, again check for errors. Press [N] to avoid executing the program then run dev guess again and make these changes:

    .model tiny
    .stack 200h
    .data
    titlemsg   db   "Guess the Number Version 1.0", 0Dh, 0Ah, '$'
    playmsg    db   "Play the game? (Y/N): $"
    promptmsg  db   0Dh, 0Ah, "Guess a number between 1 and 100 (Q=Quit): $"
    toohimsg   db   0Dh, 0Ah, "Too High!", 0Dh, 0Ah, '$'
    toolomsg   db   0Dh, 0Ah, "Too Low!", 0Dh, 0Ah, '$'
    gotitmsg   db   0Dh, 0Ah, "You got it!", 0Dh, 0Ah, '$'
    badinmsg   db   0Dh, 0Ah, "Entry must be number from 1-100 or Q!", 0Dh, 0Ah, '$'
    maxlen     db   4
    strlen     db   0
    inbuf      db   5 dup('$')
    randnum    db   0
    usernum    db   0
    placevals  db   1, 10, 100
    
    .code
    main proc
      mov ax, @data
      mov ds, ax
    start:  
      mov ah, 9
      mov dx, offset titlemsg
      int 21h
    again:  
      mov ah, 9
      mov dx, offset playmsg
      int 21h
      mov ah, 1     ;function 1: input one character and wait for it
      int 21h
      cmp al, 'y'   ;function 1 returns the char in AL
      je cont1
      cmp al, 'Y'   ;checking for either upper or lower case Y
      je cont1
      jmp terminate ;automatically quit with any other response
    cont1:
      call getrand  ;generate random number
    cont2:
      call getguess ;get the guess
      call asc2bin  ;convert it to binary
      jc cont2      ;if conversion fails asc2bin will display a msg and set the carry flag
      call chkguess ;compare it with the random number here
      jc cont2      ;if guess incorrect get another guess
      jmp again     ;if they guessed right ask to play again
    terminate:
      mov ax, 4C00h             ;function 4C = quit program
      int 21h
    main endp
    getrand proc
      mov ah, 2Ch          ;function 2Ch: get system time from BIOS
      int 21h
    ;returns CH=hour, CL=minute, DH=second, DL=1/100ths of second
    ;it is the hundredths of a second that will help generate a nice random
    ;number since it is nearly impossible to predict
      xor ax, ax      ;AX=0
      add al, ch      ;add hour
      add al, cl      ;add minute
      add al, dh      ;add second to it
      add al, dl      ;add hundredths of second to it
    ;cl now holds hour + minute + second + hundredths of a second
      mov cx, 100     ;put the value 100 in ax for the DIV instruction
      div cl          ;the DIV instruction assumes that the named register or variable
                      ;will be divided into the number in the AL register
                      ;the result will be held in the AL and the remainder 
                      ;will be left in the AH
      inc ah          ;remainders of dividing anything by 100 will be zero to 99
                      ;add 1 and the possible numbers that will be left in AH are 1 to 100
      mov randnum, ah ;store the random number that can be from 1 to 100 into the variable
      ret             ;return from the procedure
    getrand endp
    getguess proc
      mov ah, 9
      mov dx, offset promptmsg
      int 21h
    
      mov ah, 0Ah
      mov dx, offset maxlen
      int 21h
    
      ret
    getguess endp
    asc2bin proc
      xor ax, ax        ;AX=0
      mov usernum, al   ;clear unser number
      xor si, si        ;SI=0
      xor cx, cx        ;CX=0  
      mov cl, strlen    ;get the size of the string that the user entered
      mov bx, offset strlen     ;place offset of variable into BX
      mov di, offset placevals  ;place offset of place values into DI
    a2b1:
      xor dx, dx        ;DX=0
      mov si, cx        ;place offset of digit in buffer into SI
      mov dl, [bx + si] ;place ASCII digit into DL
      sub dl, 30h       ;subtract 30h leaving the binary equivalent of the digit
      mov al, [di]      ;get place value into AL
      mul dl            ;multiply dl x al result in AX
      add usernum, al   ;move the value into variable
      inc di            ;point to next place value
      loop  a2b1        ;dec 1 from cx, if cx=0 fall out of loop otherwize jmp to label
      mov al, usernum   ;retrieve usernum
      cmp al, 100       ;is it larger than 100?
      ja a2b2           ;yes jump to the error handler, otherwise ...
      clc               ;clear the carry flag,
      jmp a2bexit       ;and exit the proc
    a2b2:
      mov ah, 9
      mov dx, offset badinmsg
      int 21h
      stc               ;show error message and set the carry flag
    a2bexit:
      ret
    asc2bin endp
    
    chkguess proc
      mov al, randnum   ;get the random number that the program generated earlier
      cmp usernum, al   ;compare it with the user's guess
      jb toolow         ;jb=JUMP if BELOW
      ja toohigh        ;JA=JUMP if ABOVE
      mov ah, 9         ;if here then it must be equal (correct guess)
      mov dx, offset gotitmsg
      int 21h
      clc               ;clear carry
      jmp chkgexit
    toolow:
      mov ah, 9         ;if here then it must be too low
      mov dx, offset toolomsg
      int 21h
      stc               ;set carry
      jmp chkgexit
    toohigh:
      mov ah, 9         ;if here then it must be too high
      mov dx, offset toohimsg
      int 21h
      stc               ;set carry
    chkgexit:
      ret
    chkguess endp
    
    end main
    
  18. Save the changes and exit EDIT. Press [Y] to copy it to the floppy, [Y] to compile, [Y] to link and [N] to execute. At this point the game does work, but it does not check for the user entry of the letter "Q" as a number guess in order to quit and in fact does not check the user entry for bad data like letters and cahracters other than numbers or a "Q" at all. Run dev guess and make these changes:

    .model tiny
    .stack 200h
    .data
    titlemsg   db   "Guess the Number Version 1.0", 0Dh, 0Ah, '$'
    playmsg    db   "Play the game? (Y/N): $"
    promptmsg  db   0Dh, 0Ah, "Guess a number between 1 and 100 (Q=Quit): $"
    toohimsg   db   0Dh, 0Ah, "Too High!", 0Dh, 0Ah, '$'
    toolomsg   db   0Dh, 0Ah, "Too Low!", 0Dh, 0Ah, '$'
    gotitmsg   db   0Dh, 0Ah, "You got it!", 0Dh, 0Ah, '$'
    badinmsg   db   0Dh, 0Ah, "Entry must be number from 1-100 or Q!", 0Dh, 0Ah, '$'
    maxlen     db   4
    strlen     db   0
    inbuf      db   5 dup('$')
    randnum    db   0
    usernum    db   0
    placevals  db   1, 10, 100
    quitflag   db   0
    
    .code
    main proc
      mov ax, @data
      mov ds, ax
    start:  
      mov ah, 9
      mov dx, offset titlemsg
      int 21h
    again:  
      mov ah, 9
      mov dx, offset playmsg
      int 21h
      mov ah, 1     ;function 1: input one character and wait for it
      int 21h
      cmp al, 'y'   ;function 1 returns the char in AL
      je cont1
      cmp al, 'Y'   ;checking for either upper or lower case Y
      je cont1
      jmp terminate ;automatically quit with any other response
    cont1:
      call getrand  ;generate random number
    cont2:
      call getguess ;get the guess
      call asc2bin  ;convert it to binary
      jc cont2      ;if conversion fails asc2bin will display a msg and set the carry flag
      cmp quitflag, 1  ;is quit flag set?
      je terminate     ;yes then quit program
      call chkguess ;compare it with the random number here
      jc cont2      ;if guess incorrect get another guess
      jmp again     ;if they guessed right ask to play again
    terminate:
      mov ax, 4C00h             ;function 4C = quit program
      int 21h
    main endp
    getrand proc
      mov ah, 2Ch          ;function 2Ch: get system time from BIOS
      int 21h
    ;returns CH=hour, CL=minute, DH=second, DL=1/100ths of second
    ;it is the hundredths of a second that will help generate a nice random
    ;number since it is nearly impossible to predict
      xor ax, ax      ;AX=0
      add al, ch      ;add hour
      add al, cl      ;add minute
      add al, dh      ;add second to it
      add al, dl      ;add hundredths of second to it
    ;cl now holds hour + minute + second + hundredths of a second
      mov cx, 100     ;put the value 100 in ax for the DIV instruction
      div cl          ;the DIV instruction assumes that the named register or variable
                      ;will be divided into the number in the AL register
                      ;the result will be held in the AL and the remainder 
                      ;will be left in the AH
      inc ah          ;remainders of dividing anything by 100 will be zero to 99
                      ;add 1 and the possible numbers that will be left in AH are 1 to 100
      mov randnum, ah ;store the random number that can be from 1 to 100 into the variable
      ret             ;return from the procedure
    getrand endp
    getguess proc
      mov ah, 9
      mov dx, offset promptmsg
      int 21h
    
      mov ah, 0Ah
      mov dx, offset maxlen
      int 21h
    
      ret
    getguess endp
    asc2bin proc
      xor ax, ax        ;AX=0
      mov usernum, al   ;clear user number
      xor si, si        ;SI=0
      xor cx, cx        ;CX=0  
      mov cl, strlen    ;get the size of the string that the user entered
      mov bx, offset strlen     ;place offset of variable into BX
      mov di, offset placevals  ;place offset of place values into DI
    a2b1:
      xor dx, dx        ;DX=0
      mov si, cx        ;place offset of digit in buffer into SI
      mov dl, [bx + si] ;place ASCII digit into DL
      cmp dl, 30h       ;is it a valid digit?
      jb a2b2           ;less than 30h is always disallowed
      cmp dl, 39h      
      ja a2b3           ;above 39h could be a "Q"
    a2b4:
      sub dl, 30h       ;subtract 30h leaving the binary equivalent of the digit
      mov al, [di]      ;get place value into AL
      mul dl            ;multiply dl x al result in AX
      add usernum, al   ;move the value into variable
      inc di            ;point to next place value
      loop  a2b1        ;dec 1 from cx, if cx=0 fall out of loop otherwize jmp to label
      mov al, usernum   ;retrieve usernum
      cmp al, 100       ;is it larger than 100?
      ja a2b2           ;yes jump to the error handler, otherwise ...
      clc               ;clear the carry flag,
      jmp a2bexit       ;and exit the proc
    a2b2:
      mov ah, 9
      mov dx, offset badinmsg
      int 21h
      stc               ;show error message and set the carry flag
      jmp a2bexit
    a2b3:
      cmp dl, 'q'       ;is it a "Q"?
      je a2b5
      cmp dl, 'Q'       ;either upper or lower case is acceptable
      je a2b5
      jmp a2b2          ;if it is not a "Q" then it is no good
    a2b5:
      clc               ;clear carry
      inc quitflag      ;set quitflag=1 and fall through to the end of the proc
    a2bexit:
      ret
    asc2bin endp
    chkguess proc
      mov al, randnum   ;get the random number that the program generated earlier
      cmp usernum, al   ;compare it with the user's guess
      jb toolow         ;jb=JUMP if BELOW
      ja toohigh        ;JA=JUMP if ABOVE
      mov ah, 9         ;if here then it must be equal (correct guess)
      mov dx, offset gotitmsg
      int 21h
      clc               ;clear carry
      jmp chkgexit
    toolow:
      mov ah, 9         ;if here then it must be too low
      mov dx, offset toolomsg
      int 21h
      stc               ;set carry
      jmp chkgexit
    toohigh:
      mov ah, 9         ;if here then it must be too high
      mov dx, offset toohimsg
      int 21h
      stc               ;set carry
    chkgexit:
      ret
    chkguess endp
    end main
    
  19. Save the changes and exit EDIT. [Y] to copy, [Y] to compile, [Y] to link and [N] to execute. The game is complete and functional at this point. Run it by typing "guess" then [Enter] at the DOS prompt. Play it a few times. Try bad entries for the number guesses. Try "Q" to see if it really quits.

  20. This concludes the simple execution of a program that can gather input from a user and convert this input to the equivalent binary number and compare it with a randomly generated number. The next program will be able to use passed parameters from the command line.

Back to Page Top

Copyright©2000-2006 Brian Robinson ALL RIGHTS RESERVED