2012-04-02 17 views
5

Estoy usando NASM 16 BITS. Estoy tratando de hacer un código de ensamblaje simple que imprima los números del 0 al 255 con un intervalo de 1 segundo entre cada número. Esto es lo que tengo hasta ahora:¿Cómo mostrar un número en la pantalla y dormir durante un segundo con el ensamblado de 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 

No estoy seguro de cómo imprimir el valor de hacha en la pantalla, y cómo espere 1 segundo (los colocó en un comentario en el código).

+0

¿Estás haciendo esto en una PC? –

+0

@PavanManjunath Sí, lo estoy haciendo en una PC. Windows 7, 32 bits. –

+0

Para la parte de demora, puede ver la última publicación en [este] (http://www.physicsforums.com/showthread.php?t=150424) tema. El reloj se supone que es de 100 MHz. Pero necesita averiguar el valor exacto en su máquina a través de prueba y error. [Este] (http://www.programmersheaven.com/mb/x86_asm/272272/272273/re-sleep-function-/?S=B10000) enlace también debería ayudarlo a obtener el retraso correcto –

Respuesta

6

Hay un contador de 4 bytes en el segmento 0 offset 46Ch (o alternativamente en seg 40h, offs 6Ch) mantenido y actualizado por el PC BIOS. Se incrementa 18.2 veces por segundo. Contando 18 cambios en el byte más bajo o una palabra de este contador es probablemente la forma más sencilla de esperar a cabo de aproximadamente un segundo:

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 

Para imprimir los números decimales que necesita para convertir números binarios en decimales, llegar dígitos individuales e imprimirlas . Usted divide el número por 10 y recoge los residuos. por ejemplo:

123:
123/10: cociente 12, resto 3
12/10: cociente 1, el resto 2
1/10: cociente 0, resto 1

Al dividir repetidamente por 10 obtienes los dígitos individuales en el resto en el orden inverso: 3,2,1. Luego imprímalos usando DOS int 21h función 2 (cargue 2 en AH, cargue el código ASCII del personaje en DL, ejecute int 21h).

Una variante alternativa, muy adecuada para su problema, sería utilizar la instrucción DAA para incrementar el número directamente en decimal sin ninguna conversión.

Así es como todo se puede hacer:

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

Si no te gusta los ceros a la izquierda o la última retardo de 1 segundo, se puede omitir condicionalmente ellos.

Descargue los manuales de la CPU Intel y/o AMD x86 que describen cómo funciona cada instrucción. Léalos Además, descargue Ralf Brown's Interrupt List, que describe cada BIOS y función de DOS. Necesita conocer algunos de ellos para hacer E/S. También hay HelpPC y TechHelp que describen convenientemente muchas cosas de BIOS y DOS como el BIOS Data Area donde vive el contador antes mencionado.

+0

Este comentario es para @Alex. Funciona perfecto, muchas gracias por su generosa ayuda. Me aseguraré de leer todo lo que dijo en el comentario anterior. Solo una pregunta: ¿es difícil modificar el código que publicaste para hacer retroceder el proceso? (De 255 a 0). –

+0

Lo hice, gracias por su ayuda nuevamente @Alex –

+0

Es trivial/fácil tanto en los casos basados ​​en div como en los basados ​​en daa. –

Cuestiones relacionadas