2016-06-01 1 views
3

J'ai la fonction suivante:x86 impression étrange après console a défilée

printRows proc 
    mov cx, 25 
    printRowsLoop: 
     mov si, 0 
     printSingleRowLoop: 

      mov ah, 3 ;save current cursor position at dx (dh:dl) 
      int 10h 

      push dx ;keep the position for later 

      mov ah, 2 
      mov dl, '&' 
      int 21h  ; print '&' char in the current curser position 

      pop dx ; restore dx 

      add dl, 5 ; increase the column of it with a const number (so it would look like a square) 
      mov ah, 2 
      int 10h 

      inc si 
      cmp si, 3 ; print 3 '&' in each row 
      jne printSingleRowLoop 

     mov dl, 13  ; result of these 3 groups of commands should be 2 new lines 
     mov ah, 2 
     int 21h 

     mov dl, 10 
     ;mov ah, 2 ; ah is alredy 2 
     int 21h 

     ;mov dl, 10 ; dl is already 10 
     ;mov ah,2 ; ah is already 2 
     int 21h 

     loop printRowsLoop ; print (cx) lines 
    ret 

printRows endp 

la sortie de celui-ci doit être ce qu'on voit dans le this screenshot - ce qui est la sortie de celui-ci (au moins dans le begginig Mais, après que la "bonne" sortie ait rempli la console (quand elle a dû "défiler"), elle n'imprime plus ces espaces entre chaque '&', mais les imprime simplement dans une nouvelle ligne as can be seen here.

Qu'est-ce qui pourrait causer un comportement aussi étrange? Qu'est-ce que je fais mal? Comment devrais-je résoudre ce problème?

J'utilise emu8086.

Répondre

4

Vous devez imprimer le retour chariot (13 code ascii) en dernier. J'ai également inclus Fifoernik conseils dans ma réponse.

printRows proc 
mov cx, 25 
printRowsLoop: 
    mov si, 0 
    printSingleRowLoop: 

     push cx 
     mov bh, 0 
     mov ah, 3 ;save current cursor position at dx (dh:dl) 
     int 10h 
     pop cx 


     push dx ;keep the position for later 

     mov ah, 2 
     mov dl, '&' 
     int 21h  ; print '&' char in the current curser position 

     pop dx ; restore dx 

     mov bh, 0 
     add dl, 5 ; increase the column of it with a const number (so it would look like a square) 
     mov ah, 2 
     int 10h 

     inc si 
     cmp si, 3 ; print 3 '&' in each row 
     jne printSingleRowLoop 


     mov dl, 10 
     ;mov ah, 2 ; ah is alredy 2 
     int 21h 

     ;mov dl, 10 ; dl is already 10 
     ;mov ah,2 ; ah is already 2 
     int 21h 

     mov dl, 13 ; <<<<<<<<<<<<<<<<<<<<< print the carriage return last! 
     ;mov ah, 2 ; ah is already 2 
     int 21h 

    loop printRowsLoop ; print (cx) lines 
ret 

printRows endp 

Pas besoin d'un caractère d'espace supplémentaire :)

+0

Votre code a quelques erreurs! Autour de l'appel SetCursor vous avez écrit 'push bx' et' pop dx'. Aucun de ceux-ci sont nécessaires et à cause de l'inadéquation tout simplement faux. S'il vous plaît les enlever. –

+0

Si votre solution résout le problème du défilement, alors * emu8086 * doit être un très, très, très mauvais programme. –

+0

J'ai corrigé ces erreurs, merci. Je suppose que emu8086 est vraiment un mauvais programme (il a beaucoup de bugs). comment résoudrais-tu ce problème? – Xiobiq

2

Votre code a quelques problèmes:

  • Les fonctions du curseur du BIOS nécessitent l'argument BH à préciser. Il représente la page d'affichage. Mieux vaut le mettre à zéro.

  • L'appel au BIOS GetCursor détruira le registre CX dont vous avez besoin pour votre contrôle de boucle. Vous n'avez pas vraiment besoin des valeurs renvoyées dans CX donc juste PUSH/POP.

Utilisez ceci:

... 
push cx 
mov bh, 0 ;display page 0 
mov ah, 3 ;save current cursor position at dx (dh:dl) 
int 10h ;GetCursor 
pop cx 
... 
mov bh, 0 ;display page 0 
mov ah, 2 
int 10h ;SetCursor 
... 

Normalement ces corrections ne résoudrait pas le problème de défilement, mais EMU8086 est un programme avec beaucoup de problèmes. Vous pourriez avoir de la chance!

+0

Je sais que je devrais le faire (et je le fais dans mon code réel), je viens d'essayer d'afficher un exemple minimal, complet, vérifiable . Ces correctifs ne corrigent pas mon problème. – maniacsilversmith

+2

@maniacsilversmith: il semble que votre code soit trop minime si vous avez supprimé l'initialisation des arguments qui doivent être initialisés. Peut-être envie de mettre à jour la question à coder qui évite ces problèmes, pour plus de clarté. –

0

Le problème est la manière dont vous insérez les sauts de ligne. Ce que vous faites est d'afficher ombles 13, 10, 10. La solution est d'afficher un espace vide après les sauts de ligne (13, 10, 10, ' «):

mov dl, ' ' 
mov ah, 2 
int 21h 

Pour aligner la première ligne, nous devra afficher un autre espace au début:

printRows proc 
    mov ah, 2 ;<============================================= 
    mov dl, ' ' ;<============================================= 
    int 21h  ;<============================================= 

    mov cx, 25 
    printRowsLoop: 
     mov si, 0 
     printSingleRowLoop: 

      mov ah, 3 ;save current cursor position at dx (dh:dl) 
      int 10h 

      push dx ;keep the position for later 

      mov ah, 2 
      mov dl, '&' 
      int 21h  ; print '&' char in the current curser position 

      pop dx ; restore dx 

      add dl, 5 ; increase the column of it with a const number (so it would look like a square) 
      mov ah, 2 
      int 10h 

      inc si 
      cmp si, 3 ; print 3 '&' in each row 
      jne printSingleRowLoop 

     mov dl, 13  ; result of these 3 groups of commands should be 2 new lines 
     mov ah, 2 
     int 21h 

     mov dl, 10 
     ;mov ah, 2 ; ah is alredy 2 
     int 21h 

     ;mov dl, 10 ; dl is already 10 
     ;mov ah,2 ; ah is already 2 
     int 21h 

     mov dl, ' ' ;<============================================= 
     mov ah, 2 ;<============================================= 
     int 21h  ;<============================================= 

     loop printRowsLoop ; print (cx) lines 
    ret 

printRows endp 
+1

Est-ce vraiment un problème que votre code résout ou est-ce un bug dans emu8086 que votre code "résoudre" (comme une solution de contournement)? Je n'ai pas vraiment besoin d'un tel espace au début de chaque ligne. Je ne comprends pas pourquoi aurais-je besoin d'un, mon code original me semble correct. Pouvez-vous expliquer s'il vous plaît? – maniacsilversmith

+0

@maniacsilversmith, c'est le défilement qui confond la position du curseur. Parfois, un saut de ligne n'est pas reconnu correctement jusqu'à ce que quelque chose soit affiché. Lorsque le blanc est affiché, la position du curseur est forcée à être mise à jour, de sorte que votre code peut correctement "enregistrer" sa nouvelle position (au début de la boucle). Afficher un blanc n'est pas un gros changement dans votre code, mais c'est la solution à votre problème. –

+0

@maniacsilversmith, votre boucle affiche les sauts de ligne en bas, mais "sauvegarde" la position du curseur au début, rien n'est affiché au milieu. Après le défilement, afficher quelque chose devient nécessaire. –