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.
¿Estás haciendo esto en una PC? –
@PavanManjunath Sí, lo estoy haciendo en una PC. Windows 7, 32 bits. –
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 –