assembly 如何使用mov ah,1 int 21h进行单输入?

3xiyfsfu  于 2022-11-24  发布在  其他
关注(0)|答案(1)|浏览(249)

所以我有这个代码用于单输入,但是它每次都输出多个字符。所以现在我的问题是如何只使用int 21h ah 1应用单字符输入?
在执行此操作时仍存在困惑和问题

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: $"

我确实试过把mov ah, 1 int 21h移到所有的代码中,但是没有任何效果。我期待在一个单一的输入后,它会继续到另一个输入,然后打印出来
如何解决这个问题?
创建一个简单的控制台程序,该程序使用int 21 ah = 1 2characters只获取用户输入的年份级别和部分,然后使用机器语言在控制台上打印每个字符,输出应为2a

ztyzrc3y

ztyzrc3y1#

所以我有这个代码用于单个输入,但是它每次都输出多个字符。
您的程序当前版本使用的是DOS. BufferedInput函数0Ah,而您没有为DOS提供必要的输入结构。这就是它失败的原因。您可以阅读How buffered input works来学习如何正确使用它。
当然,就像你的任务一样,这个程序可以从使用DOS.GetCharacter function 01h中受益。它会简单得多,因为你可以将用户的响应保存在寄存器中,而不必处理缓冲区。
这个单字符输入函数在AL寄存器中传递其结果。您需要将其复制到您选择的寄存器中,但在您有机会使用该寄存器在屏幕上显示之前,该寄存器不会以任何方式被修改。寄存器BL和BH是一个很好的选择。我们将使用DOS.DisplayCharacter function 02h一个接一个地输出这两个字符。
我确实试过将mov ah, 1int 21h移到所有代码中,但没有任何效果。
从外观上看,你试图将它添加到程序中,但同时并没有删除缓冲输入功能。删除是一种强大的编程技术,你不应该害怕使用!

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: $"

和原来的程序一样,这个新程序不会很好地将消息写在彼此的下面。为此,我们需要在消息中插入回车(13)和换行符(10)代码:

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: $"

为求完美,并且由于您首先显示 * 年份级别 *("2"),其次显示 * 部分 *("a"),因此附带的消息应该一致,因此最好写为:

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

部分优化

  • 您可以将 * msg * 和 * first * 合并到一个输出中。
  • 您可以将输入的2个字符存储在 * 第三条 * 消息的一个小的专用部分中,然后一次性输出(使用DOS功能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: ??$"

为什么是mov [third + 31], almov [third + 32], al

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

下一种方法不太容易出错(由于偶尔的错误计数而出错):

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 "??$"

相关问题