2012-04-02 12 views
5

Używam NASM 16 BITS. Próbuję wykonać prosty kod zespołu, który wypisze liczby od 0 do 255 z 1-sekundową przerwą między każdą liczbą. To, co mam tak daleko:Jak wyświetlić numer na ekranie i uśpić na jedną sekundę przy użyciu zestawu DOS x86?

[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 

Nie jestem pewien, jak drukować wartość siekierą na ekranie, jak i poczekać 1 sekundę (umieścił je w komentarzu w kodzie).

+0

Czy robisz to na komputerze? –

+0

@PavanManjunath Tak, robię to na PC. Windows 7, 32 bity. –

+0

W części dotyczącej opóźnienia można sprawdzić ostatni wpis w wątku [this] (http://www.physicsforums.com/showthread.php?t=150424). Zakłada się, że zegar wynosi 100 MHz. Ale musisz wypróbować dokładną wartość na swoim komputerze za pomocą prób i błędów. [This] (http://www.programmersheaven.com/mb/x86_asm/272272/272273/re-sleep-function-/?S=B10000) link powinien również pomóc w uzyskaniu opóźnienia w prawo –

Odpowiedz

6

Istnieje 4-bajtowy licznik w segmencie 0 przesunięcie 46Ch (lub alternatywnie w seg 40h, offs 6Ch) jest utrzymywany i aktualizowany przez system BIOS komputera. Zwiększa się o 18,2 razy na sekundę. Licząc 18 zmian w najniższym bajt lub słowo z tego licznika jest prawdopodobnie najprostszym sposobem czeka się około jednej sekundy:

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 

Aby wydrukować liczb dziesiętnych potrzebne do konwersji liczb binarnych na przecinku, dostać poszczególne cyfry i wydrukować je . Dzielicie liczbę przez 10 i zbierajcie resztki. np

123:
123/10: iloraz 12, reszta 3
12/10: iloraz 1, reszta 2
1/10: iloraz 0, reszta 1

poprzez dzielenie przez 10 otrzymasz poszczególne cyfry w reszcie w odwrotnej kolejności: 3,2,1. Następnie drukujesz je za pomocą funkcji DOS int 21h 2 (załaduj 2 do AH, załaduj kod ASCII postaci do DL, wykonaj int 21h).

Alternatywnym wariantem, całkowicie odpowiadającym Twojemu problemowi, byłoby użycie instrukcji DAA w celu zwiększenia liczby bezpośrednio w systemie dziesiętnym bez jakiejkolwiek konwersji.

Oto jak to wszystko może być wykonane:

; 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,"$" 

Jeśli nie lubią zer lub ostatni 1-sekundowe opóźnienie, można je pominąć warunkowo.

Pobierz instrukcje procesora Intel i/lub AMD x86, które opisują działanie każdej instrukcji. Przeczytaj je. Pobierz także Ralf Brown's Interrupt List, który opisuje każdą funkcję BIOS i DOS. Musisz znać niektóre z nich, aby wykonać I/O. Istnieją również HelpPC i TechHelp, które wygodnie opisują wiele rzeczy z BIOS-u i DOS, takich jak BIOS Data Area, gdzie wspomniany wcześniej licznik żyje.

+0

Ten komentarz dotyczy @Alex Działa idealnie, bardzo dziękuję za hojną pomoc. Na pewno przeczytam wszystko, co powiedziałeś w powyższym komentarzu. Tylko jedno pytanie: Czy trudno jest zmienić kod, który wysłałeś, aby proces się cofnął? (Od 255 do 0). –

+0

Zrobiłem to, dziękuję za pomoc ponownie @Alex –

+0

To trywialne/łatwe w obu przypadkach opartych na div i daa. –

Powiązane problemy