desktop

Que algoritmo a emplear para hacer retraso en MASM

Buenas, quiero hacer un retraso de 3 segundos en un programa de MASM en Windows que estoy haciendo, pero no se como se hace ese algoritmo, entonces esa es mi duda.. mas abajo voy a colocar mi código de lo que estoy haciendo y estoy copilando con la versión 6.11.

Código:
.model small
.stack
.data

txt1 db "Hola Mundo.","$"

.code

inicio:

;limpiar pantalla
mov ax,0600h
mov bh,0fh
mov cx,0000h
mov dx,184fh
int 10h

; Aqui quiero poner un algoritmo o algo que haga que despues de 
; "limpiar la pantalla", suceda un retraso
; de 3 segundos. 

;posicionar txt1
mov ah,02
mov bh,0
mov dx,0
int 10h

;imprimir txt1
mov ax,@data
mov ds,ax
mov dx,offset txt1
mov ah,09
int 21h
		
;final
mov ax,4c00h
int 21h
end inicio
 
Ya lo logre el algoritmo para hacer el retraso en MASM es este:

Código:
call retardo
call retardo
call retardo

retardo:

push cx
mov cx,0FFFFh

aqui2:

push cx
mov cx,0FFh

aca:

nop
loop aca
pop cx
loop aqui2
pop cx
ret
Puedes llamar a call retardo tantas veces como quieras para hacer mas lento el retraso.

Aquí dejo un ejemplo:

Código:
.model small
.stack
.data

txt1 db "Hola Mundo.","$"

.code

inicio:

jmp inicio2

;---------------------------------------------------------------------------- RETARDADOR

retardador:

call retardo
call retardo
call retardo
call retardo
call retardo
call retardo
call retardo
call retardo
call retardo
call retardo
call retardo
call retardo
call retardo
call retardo
call retardo
call retardo
call retardo
call retardo
call retardo
call retardo
call retardo
call retardo
call retardo
call retardo
call retardo
call retardo
call retardo
call retardo
call retardo
call retardo
call retardo
call retardo
call retardo
call retardo
call retardo
call retardo
call retardo
call retardo
call retardo
call retardo
call retardo
call retardo
call retardo
call retardo
call retardo
call retardo
call retardo
call retardo
call retardo
call retardo
call retardo
call retardo
call retardo
call retardo
call retardo
call retardo
call retardo
call retardo
call retardo
call retardo
call retardo
call retardo
call retardo
call retardo
call retardo
call retardo
call retardo
call retardo
call retardo
call retardo
call retardo
call retardo
call retardo
call retardo
call retardo
call retardo
call retardo
call retardo
call retardo
call retardo
call retardo
call retardo
call retardo
call retardo
call retardo
call retardo
call retardo
call retardo
call retardo
call retardo
call retardo
call retardo
call retardo
call retardo
call retardo
call retardo
call retardo
call retardo
call retardo
call retardo
call retardo
call retardo
call retardo
call retardo
call retardo
call retardo
call retardo
call retardo
call retardo
call retardo
call retardo
call retardo
call retardo
call retardo
ret

retardo:

push cx
mov cx,0FFFFh

aqui2:

push cx
mov cx,0FFh

aca:

nop
loop aca
pop cx
loop aqui2
pop cx
ret

;---------------------------------------------------------------------------- INICIO

inicio2:

;limpiar pantalla
mov ax,0600h
mov bh,0fh
mov cx,0000h
mov dx,184fh
int 10h

;posicionar txt1
mov ah,02
mov bh,0
mov dx,0
int 10h

;imprimir txt1
mov ax,@data
mov ds,ax
mov dx,offset txt1
mov ah,09
int 21h

;---------------------------------------------------------------------------- FINAL

call retardador

final:
mov ax,4c00h
int 21h
end inicio
Existe una forma con el temporizador del procesador, pero no tengo ni idea...
 
Última edición:
Ya lo logre el algoritmo para hacer el retraso en MASM es este:
......................
......................
Existe una forma con el temporizador del procesador, pero no tengo ni idea...
Por lo visto un código minimamente optimizado no te importa en absoluto (n).
Además, esa rutina no sirve porque dependés de la velocidad de la máquina.


Los retardos en DOS siempre fueron una incomodidad porque por esas cosas ridículas de Micro$oft, jamás les importó agregar un servicio estandar con resolución aceptable.

Hasta la llegada de XP, lo mas sencillo era usar un servicio extendido del BIOS.
Era la INT 15h,AH=86h que consistia en un retardo de microsegundos en 32 bit (1hora 11min máximo)
Simplemente creabas un macro
Código:
retardo macro N_uS_H,N_uS_L
          mov cx,N_uS_H
          mov dx,N_uS_L
          mov ah,86h
          int 15h
          endm
y después lo llamabas
Código:
          retardo 2ch,0C6C0h  ;  3seg
Lamentablemente, no corre mas... :cry:

Así que lo más simple que queda, es hacer una rutina que lea la variable del sistema 40:6C que lleva la cuenta del número de tics (~55ms) desde las 0h
Y lamentablemente, como con todo producto de Micro$oft, encima de la porbre resolución hay que hacerle un ajuste porque resetea el contador cuando llega a 1800B0h (24hs)

Podés leer directamente la variable cambiando temporalmente el registro de segmento DS (o usando ES) o hacerlo levemente mas compacto usando la INT 1Ah,AH=0
Algo que puede ser así:
Código:
retardo proc        ; AX = Ntimer_tics
        mov bx,ax
        sub ah,ah
        int 1Ah
        add bx,dx
        adc cx,0
       ;- Ajuste pasadas 24hs
        cmp cx,18h
        jnz L0
        cmp bx,00B0h
        jb  L0
        sub bx,00B0h
        ;----------
L0:     sub ah,ah
        int 1Ah
        cmp bx,dx
        ja L0
        ret
retardo endp
despues la llamás con:
Código:
        mov ax,48   ; 48 tics ~ 3 seg
        call retardo
Hay muchas otras maneras, todas con ventajas y desventajas. Pero para el tipo de retardo que querés hacer, creo que lo mas simple es de esta forma.
 
Última edición:
Atrás
Arriba