Midorin
Midorin

Reputation: 13

How use mov ah,1 int 21h for single inputs?

So I have this code for single input but it does output multiple characters every time. So now my question is how to apply the single character input only using int 21h ah 1?

Still confused and problematic on doing this

org 100h   

mov dx, offset msg
mov ah, 9
int 21h

mov dx, offset first
mov ah, 9
int 21h   


mov dx, offset inp 
mov ah, 0ah                ; get output
int 21h       


mov ah, 1   
mov ah, 2
            

mov dx, offset second
mov ah, 9
int 21h               
            
mov dx, offset inp2
mov ah, 0ah                ; get output
int 21h       


mov ah, 1   
mov ah, 2  

mov dx, offset third
mov ah, 9
int 21h 

JMP OUTPUT:
   
inp db 10, ?, 10 dup('')  
inp2 db 10, ?, 10 dup('')
   
   
OUTPUT:         
mov ah, 1
mov ah, 2


mov dl, 13
int 21h 

mov dl, 10
int 21h

mov bl, inp[1]
mov inp[bx+2], "$"


mov dx, offset inp +2
mov ah, 9                    ; code for output
int 21h

mov bl, inp2[1]
mov inp2[bx+2], "$"


mov dx, offset inp2 +2
mov ah, 9
int 21h    



ret

msg db "Welcome to Single Character output", 13, 10, "$"      
first db  "Put your Year level: $"      
second db "Put your section:  $"
third db "Your section and year level is: $"
fourth db "Input: $"

I did try moving in the mov ah, 1 int 21h into all codes but nothing works. I am expecting after a single input it will proceed to another input then print it out

How to fix this?

Create a simple console program that gets the user input using int 21 ah=1 2characters only year level and section and then prints every character on the console using machine language the output should be 2a

Upvotes: 0

Views: 1136

Answers (1)

Sep Roland
Sep Roland

Reputation: 39166

So I have this code for single input but it does output multiple characters every time.

The current version of your program is using the DOS.BufferedInput function 0Ah, and you are not providing the necessary input structure to DOS. That's why it fails. You can read How buffered input works to learn how to use it properly.

Of course, just like you were tasked, this program can benefit from using the DOS.GetCharacter function 01h. It will be much simpler since you can keep the user's response in registers, not having to deal with buffers.
This single character input function delivers its result in the AL register. You need to copy it to a register of your choice, but one that is not going to get modified in any way before you get the chance to use the register for displaying on the screen. The registers BL and BH make a good choice. We will use the DOS.DisplayCharacter function 02h to output the 2 characters one after the other.

I did try moving in the mov ah, 1 int 21h into all codes but nothing works.

From the looks of it, you were trying to add it to the program but were not removing at the same time the buffered input functionality. Deletion is a powerful programming technique that you should not be afraid to use!

org 256

mov dx, offset msg
mov ah, 09h   ; DOS.DisplayString
int 21h

mov dx, offset first
mov ah, 09h   ; DOS.DisplayString
int 21h   

mov ah, 01h   ; DOS.GetCharacter
int 21h       ; -> AL
mov bl, al

mov dx, offset second
mov ah, 09h   ; DOS.DisplayString
int 21h               
            
mov ah, 01h   ; DOS.GetCharacter
int 21h       ; -> AL
mov bh, al

mov dx, offset third
mov ah, 09h   ; DOS.DisplayString
int 21h 

mov dl, bl     ; Year level
mov ah, 02h    ; DOS.DisplayCharacter
int 21h

mov dl, bh     ; Section
mov ah, 02h    ; DOS.DisplayCharacter
int 21h

ret

msg db "Welcome to Single Character output", 13, 10, "$"      
first db  "Put your Year level: $"      
second db "Put your section:  $"
third db "Your section and year level is: $"

Much like it was in the original program, this new program will not nicely write the messages below each other. For that to happen we need to insert the carriage return (13) and linefeed (10) codes in our messages:

msg    db "Welcome to Single Character output$"
first  db 13, 10, "Put your year level: $"
second db 13, 10, "Put your section: $"
third  db 13, 10, "Your section and year level is: $"

For perfection, and because you firstly display the year level ("2") followed in second place by the section ("a"), the accompanying message should accord, so better write:

third  db 13, 10, "Your year level and section: $"

Some optimizations

  • You can combine msg and first in a single output.
  • You can store the 2 inputted characters in a small dedicated portion within the third message that you then output in one go (with DOS function 09h).
org 256

mov dx, offset first
mov ah, 09h   ; DOS.DisplayString
int 21h   

mov ah, 01h   ; DOS.GetCharacter
int 21h       ; -> AL
mov [third + 31], al

mov dx, offset second
mov ah, 09h   ; DOS.DisplayString
int 21h               
            
mov ah, 01h   ; DOS.GetCharacter
int 21h       ; -> AL
mov [third + 32], al

mov dx, offset third
mov ah, 09h   ; DOS.DisplayString
int 21h 

ret

first  db "Welcome to Single Character output$"
       db 13, 10, "Put your year level: $"
second db 13, 10, "Put your section: $"
third  db 13, 10, "Your year level and section: ??$"

Why mov [third + 31], al and mov [third + 32], al ?

third  db 13, 10, "Your year level and section: ??$"
          <----------- [third + 31] ----------->
          <------------ [third + 32] ----------->

A bit less error prone (erroring due to the occasional miscounting) is next approach:

org 256

mov dx, offset first
mov ah, 09h   ; DOS.DisplayString
int 21h   

mov ah, 01h   ; DOS.GetCharacter
int 21h       ; -> AL
mov [third_], al

mov dx, offset second
mov ah, 09h   ; DOS.DisplayString
int 21h               
            
mov ah, 01h   ; DOS.GetCharacter
int 21h       ; -> AL
mov [third_ + 1], al

mov dx, offset third
mov ah, 09h   ; DOS.DisplayString
int 21h 

ret

first  db "Welcome to Single Character output$"
       db 13, 10, "Put your year level: $"
second db 13, 10, "Put your section: $"
third  db 13, 10, "Your year level and section: "
third_ db "??$"

Upvotes: 1

Related Questions