2012-04-02 3 views
5

Ich benutze NASM 16 BITS. Ich versuche, einen einfachen Assemblercode zu erstellen, der die Zahlen von 0 bis 255 mit einem Intervall von 1 Sekunde zwischen jeder Zahl ausgibt. Das ist, was ich habe, so weit:Wie kann ich eine Nummer auf dem Bildschirm anzeigen und für eine Sekunde mit der DOS x86-Baugruppe schlafen?

[bits 16] 

mov ax,cs 
mov ds,ax 
mov cx,255 
mov ax,0 

myloop: 
    ;print in screen ax value 
    ;wait 1 second 
    inc ax 

loop myloop 

Ich bin nicht sicher, wie der Wert der Axt auf dem Bildschirm zu drucken, und wie 1 Sekunde warten (sie in einem Kommentar in dem Code platziert).

+0

Machst du das auf einem PC? –

+0

@PavanManjunath Ja, ich mache es auf einem PC. Windows 7, 32 Bit. –

+0

Für den Verzögerungsteil kannst du den letzten Beitrag im [this] (http://www.physicsforums.com/showthread.php?t=150424) Thread ansehen. Der Takt wird als 100 MHz angenommen. Aber Sie müssen den genauen Wert auf Ihrem Computer durch Versuch und Irrtum herausfinden. [This] (http://www.programsheaven.com/mb/x86_asm/272272/272273/re-sleep-function-/?S=B10000) Link sollte Ihnen auch helfen, die Verzögerung richtig zu bekommen –

Antwort

6

Am Segment 0-Offset 46Ch (oder alternativ an Segment 40h, Offs 6Ch) wird ein 4-Byte-Zähler vom PC-BIOS verwaltet und aktualisiert. Es ist 18,2 mal pro Sekunde erhöht. 18 Änderungen im untersten Byte oder Wort dieses Zählers zu zählen ist wahrscheinlich der einfachste Weg, etwa des Wartens aus einem zweiten:

mov ax, 0 
mov ds, ax 
mov cx, 18 
mov bx, [46Ch] 
WaitForAnotherChange: 
NoChange: 
mov ax, [46Ch] 
cmp ax, bx 
je NoChange 
mov bx, ax 
loop WaitForAnotherChange 

Dezimalzahlen drucken Sie Binärzahlen in dezimal konvertieren müssen, einzelne Ziffern erhalten und ausdrucken . Sie teilen die Zahl durch 10 und sammeln Reste. Beispiel:

123:
123/10: Quotient 12, Rest 3
12/10: Quotient 1, Rest 2
1/10: Quotient 0, Rest 1

Durch Teile wiederholt von 10 Sie erhalten die einzelnen Ziffern in den Resten in umgekehrter Reihenfolge: 3,2,1. Dann drucken Sie sie mit DOS int 21h Funktion 2 (laden Sie 2 in AH, laden Sie den ASCII-Code des Zeichens in DL, führen Sie int 21h aus).

Eine alternative Variante, die für Ihr Problem sehr geeignet ist, wäre die Verwendung der Anweisung DAA, um die Zahl direkt im Dezimalwert ohne Konvertierung zu erhöhen.

Hier ist, wie es getan werden kann:

; file: counter.asm 
; assemble: nasm.exe counter.asm -f bin -o counter.com 

bits 16 
org 0x100 

    mov ax, 0 ; initial number 
    mov cx, 256 ; how many numbers 

NextNumber: 
%if 1 ; change to 0 to use the DAA-based method 
    push ax 

    mov dx, 0 
    div word [ten] 
    push dx 

    mov dx, 0 
    div word [ten] 
    push dx 

    mov dx, 0 
    div word [ten] 
    push dx 

    pop dx 
    call PrintDigit 
    pop dx 
    call PrintDigit 
    pop dx 
    call PrintDigit 

    pop ax 

    call PrintNewLine 
    call Wait1s 

    inc ax 
%else 
    mov dl, ah 
    call PrintDigit 

    mov dl, al 
    shr dl, 4 
    call PrintDigit 

    mov dl, al 
    and dl, 0Fh 
    call PrintDigit 

    call PrintNewLine 
    call Wait1s 

    add al, 1 
    daa 
    adc ah, 0 
%endif 

    loop NextNumber 
    ret 

PrintDigit: 
    pusha 
    mov ah, 2 
    add dl, '0' 
    int 21h 
    popa 
    ret 

PrintNewLine: 
    pusha 
    mov dx, CRLF 
    mov ah, 9 
    int 21h 
    popa 
    ret 

Wait1s: 
    pusha 
    push ds 

    mov ax, 0 
    mov ds, ax 

    mov cx, 18 
    mov bx, [46Ch] 
WaitForAnotherChange: 
NoChange: 
    mov ax, [46Ch] 
    cmp ax, bx 
    je NoChange 
    mov bx, ax 
    loop WaitForAnotherChange 

    pop ds 
    popa 
    ret 

ten dw 10 
CRLF db 13,10,"$" 

Wenn Sie die führenden Nullen nicht mögen oder die letzten 1-Sekunden-Verzögerung, können Sie sie bedingt überspringen.

Laden Sie Intel und/oder AMD x86 CPU Handbücher herunter, die beschreiben, wie jede Anweisung funktioniert. Lese sie. Laden Sie auch die Ralf Brown's Interrupt List herunter, die jede BIOS- und DOS-Funktion beschreibt. Sie müssen einige von ihnen kennen, um I/O zu tun. Es gibt auch HelpPC und TechHelp, die bequem viele BIOS- und DOS-Dinge wie die beschreiben, wo der oben genannte Zähler lebt.

+0

Dieser Kommentar ist für @Alex Es funktioniert perfekt, vielen Dank für Ihre großzügige Hilfe. Ich werde sicherstellen, alles zu lesen, was Sie in dem obigen Kommentar gesagt haben. Nur eine Frage: Ist es schwierig, den von Ihnen geposteten Code zu ändern, um den Prozess rückgängig zu machen? (Von 255 bis 0). –

+0

Ich tat es, danke für Ihre Hilfe wieder @Alex –

+0

Es ist trivial/einfach in den div-basierten und den daa-basierten Fällen. –

Verwandte Themen