The Main program is slightly more complicated and you need to think about the I/O process. First of all, for most applications you do not call the low level routines GetChar and PutChar. They are used by the higher level I/O subroutines that you wrote for reading and writing strings and numbers.
Secondly, you cannot just call an input routine like GetStr or GetNum on its own. Think carefully about what would happen. Let's say at some point in your program you want to read a number from the keyboard and place it in a memory location. Consider the following code fragment:
MyNum: dw
Main:
...
...
call GetNum
mov MyNum1, ax
This code will assemble and run and when you enter a number and press ‘Enter' it will store the number at location MyNum. However, how does the person running the program know when to enter a number, or whether to enter a number or a string? When subroutine GetNum is called it will simply wait for input from the keyboard. But the program gives no indication that it is waiting for input! The simple answer is that you must always first write a string to the screen asking for the kind of input you want the user to enter, then call the appropriate input routine. So, our revised program should look like this:
Prompt1: db ‘Enter a number less than 65536:
MyNum: dw
Main:
...
...
Mov ax, Prompt1
Call PutStr
call GetNum
mov MyNum1, ax
Now when the program runs it first prints a message asking for a number and then waits for input. Try this out - if you have written your routines correctly, I think you will like the way this works.