我不明白如何使用中断21,AH = 0ah

时间:2012-11-03 06:27:02

标签: assembly dos interrupt bios tasm

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

我不知道如何从int21 / AH = 0ah访问输入。除非我理解上面链接的内容,否则我真的不能问更准确的问题。谁能解释一下?此外,如果这有任何区别,我正在使用TASM。另外,我正在对freedos进行测试。

UPDATE1:

好的,多亏了你的帮助,我相信我理解中断是如何设置和行为的。

设置: 我必须指定一个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

3 个答案:

答案 0 :(得分:8)

该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

如何转换为大写留给读者。

答案 1 :(得分:1)

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

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

答案 2 :(得分:0)

.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