2012-11-03 15 views
9

Meine Informationen stammen aus here. Die Zuweisung fragt nach einem Programm, das nicht mehr als 20 Zeichen einliest, diese Zeichen in Großbuchstaben umwandelt und die Eingabe dann als Großbuchstaben druckt.Ich verstehe nicht, wie Interrupt 21 zu verwenden, AH = 0ah

Ich habe keine Ahnung, wie Sie auf die Eingabe von int21/AH = 0ah zugreifen. Ich kann wirklich keine genauere Frage stellen, wenn ich nicht verstehe, was oben verlinkt ist. Kann jemand das erklären? Außerdem verwende ich TASM, wenn das einen Unterschied macht. Außerdem teste ich das auf Freedos.

UPDATE1:

Ordnung, dank Ihrer Hilfe, ich glaube, ich verstehe, wie die Interrupt eingerichtet werden, muss und verhält.

Setup: I mit einem DS bezeichnen muss: dx, wo ich diese Puffer will

I ds setzen müssen existieren: dx bis 20 (die die maximale Anzahl von Zeichen setzt der Puffer halten kann)

ich habe ds einzustellen: dx + 1 bis 0 (was ich denke, irgendwie eine min Anzahl von Zeichen auf lesen)

Eigentlich nennen INT21/AH = 0Ah, die ds gehen: dx und interpretieren Sie die voreingestellten Bytes. Es wird das Programm zu stoppen, während es für die Eingabe wartet

INT21/AH = 0Ah von ds füllen wird: dx + 2 + n mit meinem Eingang (wobei n die Anzahl der eingegebenen Zeichen einschließlich ‚\ r‘)

Meine Frage ist jetzt, wie mache ich das. Ich habe gerade die x86 Assembly Language Reference erneut durchgesehen, konnte aber noch nichts hilfreiches finden.

-Code Ich habe bisher bekam

  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 

Antwort

6

Das DOS-Funktion einen Puffer mit Benutzereingabe abruft. Siehe hierzu table. Es scheint, dass das Programm diesen Aufruf verwendet, um die Ausführung anzuhalten und darauf zu warten, dass der Benutzer das Programm wieder aufnimmt.

Edit: Ich habe gerade die Frage neu gelesen. Ich dachte, du fragst nur, was der Funktionsaufruf in deiner Quelle gemacht hat. Wenn Sie eine Eingabe von nicht mehr als 20 Zeichen lesen möchten, benötigen Sie zuerst Speicher, um sie zu speichern. In etwa so:

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

dann den Puffer füllen:

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 

Wie konvertiert wird den Leser in Großbuchstaben links.

+0

Dann verhält es sich wie int21/AH = 1h, die in einem einzelnen Zeichen liest. Ich weiß, dass dieser Interrupt das Zeichen in das Register AL bringt. Wie würde ich herausfinden, wo der Puffer von Charakteren wäre? –

+0

Auch habe ich gerade realisiert. Die Offset-Tabelle bedeutet, dass die tatsächlichen Zeichendaten bei zwei Bits oder Bytes (wahrscheinlich Bytes) beginnen, von wo die Rückkehrdaten im Speicher existieren. Gedanken? –

+0

Ja, die tatsächliche Eingabe beginnt bei DS: DX + 2. Diese Datei ignoriert jedoch diese Eingabe und verwendet diese Funktion nur, um die Ausführung anzuhalten. –

1

Diese Beschreibung sagt, dass Sie die Adresse eines Puffers in ds:dx setzen, bevor Sie den Interrupt aufrufen. Der Interrupt füllt dann diesen Puffer mit den gelesenen Zeichen.

Vor dem Aufruf des Interrupts ist das erste Byte des Puffers, wie viele Zeichen der Puffer enthalten kann, oder 20 in Ihrem Fall. Ich verstehe die Beschreibung des zweiten Bytes des Puffers (bei Eingabe des Interrupts) nicht, also würde ich ihn auf Null setzen. Bei der Rückgabe sagt Ihnen dieses Byte, wie viele Zeichen der Eingabe gelesen und in den Puffer eingegeben wurden.

+0

So, wie ich Ihre Erklärung verstehe, ist die Adresse, wo ich den Puffer finden kann, über die Register ds und dx aufgeteilt. –

+0

Frage, gib mir eine Minute, um darüber nachzudenken. –

+0

(Tippfehler) Sortieren. 'ds' ist das Segmentregister; 'dx' ist der Offset. Und Sie "finden" den Puffer nicht; Sie stellen _ den Puffer bereit, indem Sie 'ds' und' dx' setzen, um darauf zu zeigen, bevor Sie den Interrupt aufrufen. (Sie müssen auch die ersten zwei Bytes des Puffers vor dem Aufrufen des Interrupts setzen. Der Puffer - und seine ersten zwei Bytes - sind Eingaben für den Interrupt.) - Nemo vor 11 Minuten – 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