2012-11-03 24 views
9

Moje informacje pochodzą z here. Przypisanie prosi o program, który czyta nie więcej niż 20 znaków, zamienia te znaki na wielkie litery, a następnie wypisze dane wejściowe jako wielkie litery.Nie rozumiem, jak używać Przerwania 21, AH = 0ah

Nie mam pojęcia, jak uzyskać dostęp do wejścia z int21/AH = 0ah. Naprawdę nie mogę zadać bardziej precyzyjnego pytania, chyba że rozumiem, co jest połączone powyżej. Czy ktoś może wyjaśnić? Używam również TASM, jeśli to robi jakąkolwiek różnicę. Ponadto testuję to na freedos.

UPDATE1:

porządku, dzięki waszej pomocy, wierzę Rozumiem, jak wymaga przerwania należy ustawić się i zachowuje.

Setup: muszę wyznaczyć ds: dx gdzie chcę to bufor istnieć

muszę ustawić ds: dx do 20 (która określa maksymalną liczbę znaków bufor może pomieścić)

muszę ustawić ds: dx + 1 do 0 (co moim zdaniem jakoś ustawić numer min znaków czytać w)

Właściwie zadzwonić int21/AH = 0AH, która trafi do DS: DX interpretować ustawione bajty. Będzie zatrzymać program podczas oczekiwania na wejście

int21/AH = 0AH wypełni DS: DX + 2 + n z mojego wejścia (gdzie n oznacza numer wejścia znaków ze '\ r')

Moje pytanie brzmi teraz, jak to zrobić. Właśnie przejrzałem x86 Assembly Language Reference, ale jeszcze nie znalazłem nic przydatnego.

kod mam tak daleko

  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 

Odpowiedz

6

To funkcja DOS pobiera buforze o dane wprowadzone przez użytkownika. Zobacz to table. Wygląda na to, że program używa tego wywołania, aby wstrzymać wykonanie, czekając, aż użytkownik wznowi działanie programu.

Edycja: Właśnie przeczytałem ponownie pytanie. Myślałem, że pytasz tylko, co wywołała funkcja w twoim źródle. Jeśli chcesz odczytać dane wejściowe o długości nie większej niż 20 znaków, potrzebujesz najpierw pamięci do jej zapisania. Dodaj coś takiego:

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

Następnie napełnić bufor:

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 

Jak przekonwertować na wielkie pozostawiamy czytelnikowi.

+0

Wtedy zachowuje się jak int21/AH = 1h, który czyta się w jednym znaku. Wiem, że to przerwanie powoduje wpisanie postaci do rejestru AL. Jak mógłbym określić, gdzie będzie bufor postaci? –

+0

Ponadto, właśnie zdałem sobie sprawę. Tabela przesunięć oznacza, że ​​rzeczywiste dane znakowe zaczynają się od dwóch bitów lub bajtów (prawdopodobnie bajtów) z dala od miejsca, w którym dane zwrotne istnieją w pamięci. Myśli? –

+0

Tak, rzeczywiste wejście zaczyna się od DS: DX + 2. Jednak ten plik ignoruje to wejście i używa tylko tej funkcji do wstrzymania wykonywania. –

1

Ten opis mówi, że wpisujesz adres bufora w ds:dx przed wywołaniem przerwania. Przerwanie wypełni ten bufor znakami, które odczytuje.

Przed wywołaniem przerwania, pierwszy bajt bufora określa ile znaków może pomieścić bufor, lub 20 w twoim przypadku. Nie rozumiem opisu drugiego bajtu bufora (na wejściu do przerwania), więc ustawiłbym go na zero. Po powrocie ten bajt informuje, ile znaków wejściowych zostało odczytanych i umieszczonych w buforze.

+0

Więc jak rozumiem twoje wyjaśnienie, adres gdzie mogę znaleźć bufor jest podzielony na rejestry ds i dx. –

+0

moot question, daj mi minutę, aby pomyśleć o powyższym. –

+0

(poprawianie literówki) Sortuj. 'ds' to rejestr segmentów; 'dx' jest przesunięciem. I nie "znajdujesz" bufora; buforujesz bufor, ustawiając "ds" i "dx", aby wskazywały na niego przed wywołaniem przerwania. (Musisz również ustawić pierwsze dwa bajty bufora przed wywołaniem przerwania.Bufor - i jego pierwsze dwa bajty - są wejściami do przerwania). - Nemo 11 min temu – Nemo

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