【问题标题】:I don't understand how to use Interrupt 21, AH=0ah我不明白如何使用中断 21,AH=0ah
【发布时间】:2012-10-23 18:51:32
【问题描述】:

我的信息来自here。该作业要求一个程序读取不超过 20 个字符,将这些字符转换为大写,然后将输入打印为大写。

我不知道如何从 int21/AH=0ah 访问输入。除非我了解上面链接的内容,否则我真的无法提出更准确的问题。有人可以解释吗?另外,如果这有什么不同,我正在使用 TASM。另外,我正在 freedos 上对此进行测试。

更新1:

好的,感谢您的帮助,我相信我了解中断需要如何设置和行为。

设置: 我必须指定一个 ds:dx 我希望此缓冲区存在的位置

我必须将 ds:dx 设置为 20(设置缓冲区可以容纳的最大字符数)

我必须将 ds:dx+1 设置为 0(我认为它以某种方式设置了要读取的最小字符数)

其实调用int21/AH=0ah,会去ds:dx解释预设的字节。它会在等待输入时暂停程序

int21/AH=0ah 将从 ds:dx+2+n 填充我的输入(其中 n 是输入的字符数,包括 '\r')

我现在的问题是,我该怎么做。我刚刚再次浏览了 x86 汇编语言参考,但还没有找到任何有用的东西。

到目前为止我得到的代码

           assume          cs:code,ds:code
code       segment
start:

           mov  ax,code ;moves code segment into reg AX
           mov  ds,ax   ;makes ds point to code segment

           mov  ah,0ah
           int  21h
           mov  ax,1234h  ;breakpoint

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

endNow:
           ;;;;;;;;;;ends program;;;;;;;;;;
           mov  ah,0  ;terminate program
           int  21h   ;program ends

message    db   'Hello world!!!',13,10,'$'
code       ends
           end  start

【问题讨论】:

    标签: assembly dos interrupt bios tasm


    【解决方案1】:

    该 DOS 函数使用用户输入检索缓冲区。请参阅此table。似乎程序正在使用该调用来暂停执行,等待用户恢复程序。

    编辑:我刚刚重读了这个问题。我以为你只是在问函数调用在你给定的源代码中做了什么。如果要读取不超过 20 个字符的输入,首先需要内存来存储它。添加如下内容:

    bufferSize  db 21  ; 20 char + RETURN
    inputLength db 0   ; number of read characters
    buffer      db 21 DUP(0) ; actual buffer
    

    然后填充缓冲区:

    mov ax, cs
    mov ds, ax ; ensure cs == ds
    mov dx, offset bufferSize ; load our pointer to the beginning of the structure
    mov ah, 0Ah ; GetLine function
    int 21h
    

    如何转成大写留给读者。

    【讨论】:

    • 然后它的行为类似于 int21/AH=1h 读取单个字符。我知道该中断将字符放入寄存器 AL。我如何确定字符缓冲区的位置?
    • 另外,我刚刚意识到。偏移表意味着实际的字符数据开始于远离内存中返回数据的两个位或字节(可能是字节)。想法?
    • 是的,实际输入从 DS:DX + 2 开始。但是,此文件忽略该输入,仅使用该函数暂停执行。
    • 是的,我最初的问题是中断的行为方式,因为如果我只是问如何实现它,我将不知道您刚刚发布的意思。非常感谢您的帮助。
    • 不应该是 mov dx, offset buffer 而不是 mov dx, offset bufferSize 吗?为什么它在前 2 个字节显示垃圾值?这是否意味着如果我必须读取 9 个字符(包括字符串终止符),我会再添加 2 个字符(前 2 个垃圾值)9 + 2 = 11 个字节?
    【解决方案2】:

    该描述说您在调用中断之前将缓冲区的地址放入ds:dx。然后,中断将用它读取的字符填充该缓冲区。

    在调用中断之前,缓冲区的第一个字节是缓冲区可以容纳多少个字符,或者在您的情况下为 20 个。我不明白缓冲区第二个字节的描述(在中断的输入上),所以我将它设置为零。返回时,该字节会告诉您有多少输入字符被读取并放入缓冲区。

    【讨论】:

    • 所以我如何理解您的解释,我可以找到缓冲区的地址被拆分为寄存器 ds 和 dx。
    • 没有实际意义的问题,请给我一分钟时间考虑以上问题。
    • (修正错字)有点。 ds是段寄存器; dx 是偏移量。而且您没有“找到”缓冲区;您提供缓冲区,方法是在调用中断之前将dsdx 设置为指向它。 (您还需要在调用中断之前设置缓冲区的前两个字节。缓冲区 - 及其前两个字节 - 是中断的输入。) – Nemo 11 分钟前
    【解决方案3】:
    .model small
    .stack 100h
    .data 
        N db ?
        msg db 10,13,09,"Enter number of arrays---->$"
    .code   
    .startup
        mov ax,@data
        mov ds,ax
        call read_N;read N from console
    
    
    
    
        mov ah,4ch
        int 21h  
    
    Read_N  proc
        ;get number of arrays from user
    
        push ax
        push dx
    
     readAgain:   
    
        mov ax,03h ;Clear screen
        int 10h
    
        mov dx,offset msg
        mov ah,09h
        int 21h
    
        call ReadNumber
    
        ;Inuput number must be in 2<=N<=10 bounery  
        cmp al,2
        js readAgain ;input out of boundary read again
        cmp al,10
        jg readAgain 
        mov N,al
        pop dx
        pop ax
        ret
    Read_N endp
    
    ReadNumber proc
        ;read decimal number 0-99 using 
        ;character by character in askii and conver in to decimal   
        ;return result in al
        xor ax,ax
        xor bx,bx
        xor dx,dx
    
        mov ah,01h
        int 21h
    
        sub al,'0'  ;conver in to decimal
        mov bl,al  
    
        mov ah,01h
        int 21h 
        cmp al,0dh  ;Exit if enter pressed
        jnz cont  
        mov al,bl
        jmp exit
      cont:
        sub al,'0'  ;conver in to decimal
        mov dl,al  
    
        xor al,al
        xor bh,bh
        mov cx,bx
      addnum:    
        add al,10
     loop addnum  
    
        add al,dl
      exit:   
      ret
     ReadNumber endp  
    
    end           
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-04-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-07-21
      • 1970-01-01
      相关资源
      最近更新 更多