2017-06-02 5 views
2

Je travaille sur un projet pour l'école en assembleur 8086 (en utilisant DOSBox), et j'essayais de retarder mon programme de 0,5 seconde.Retarder le programme en int 21h avec ah = 2Ch

J'ai essayé de créer une boucle qui compare l'heure actuelle au temps initial, en utilisant 21H, fonction 2Ch avec la valeur de centièmes DL, mais il semble être trop lent ...

mov ah, 2Ch 
int 21h 
mov al, dl ;hundredths 
mov bx, 0 
wait_loop: 
    one_hun: 
     int 21h 
     cmp al, dl 
     je one_hun 
    mov al, dl 
    inc bx 
    cmp bx, 50 
    jne wait_loop 

Répondre

4

Je préfère utiliser le BIOS int 1Ah, qui est utilisé comme source pour ce service int 21h de toute façon, et cela peut être un peu plus simple à utiliser. Mais attention, par défaut (à moins que vous n'ayez l'intention de reprogrammer la minuterie), cela coche 18,2 fois par seconde, donc attendre une demi-seconde, vous pouvez attendre 9 (environ 440 à 494,51 ms) ou 10 (cca 495 à 549.45 ms), la précision sera limitée à la valeur par défaut + - ~ 50ms). Si vous reprogrammez les puces de minuterie, vous pouvez obtenir une précision un peu plus élevée, mais ne vous attendez pas à ce que quelque chose comme [dix] milliers de secondes fonctionne parfaitement sous DOS (probablement émulé sous OS moderne).


À propos de votre code actuel: les centièmes du dl ne sont pas incrémentant par un, de sorte que vous comptent dans le bx le nombre de ceux 18.2Hz tiques, pas les centièmes (votre code attend ~ 2.7s , droite?).

aussi ne pas faire je dans un code similaire, toujours la condition <= ou >=, parce que si pour une raison quelconque (OS n'a pas exécuté votre code pendant un certain temps) manque cette différence exacte 50 centièmes, vous allez créer la boucle qui se déroulera presque infiniment (jusqu'à ce qu'il atteigne exactement 50 par hasard après l'un des débordements).

Pour ce faire votre chemin, vous devez calculer le delta:

mov ah, 2Ch 
    int 21h 
    mov al, dl ;hundredths 
wait_loop: 
     nop  ; burn the CPU a bit less 
     int 21h 
     sub dl,al ; calculate delta of hundredths (-99..+99) 
     jnc delta_positive 
     add dl,100 ; adjust the delta to be positive 1-99 
delta_positive: 
     cmp dl,50 
     jb wait_loop 
+0

Merci, résolu le problème! – Shelly

+0

Comment ont-ils décidé de 18.2 fois par seconde? Cela semble bizarre. – fuz

+4

@fuz essentiellement pour le débordement 16/32 bits complet (65536/18,2 = ~ 3600 = 1 heure) plus la fréquence initiale de cristal: https://blogs.msdn.microsoft.com/oldnewthing/20041202-00/?p= 37153 – Ped7g