2017-09-23 19 views
1

J'ai donc commencé à écrire un "noyau" pour ainsi dire et j'essaye de lire une chaîne et de l'imprimer moi. Le problème vient quand je l'exécute et il imprime juste 3 du même caractère au lieu de ce que j'ai écrit sur la ligne.Mes fonctions de lecture et d'écriture crachent %%% au lieu des 3 caractères que j'ai mis

read_string: 
    call newline 
    mov si, read_attempt 
    call print 
    call newline 
    push bx 
    mov ah, 0x03 
    int 0x10 
    mov dl, 0 
    int 0x10 
        ;read 1st char 
    mov ah, 0x08 
    int 0x10 
    mov bl, al 
    pop bx 
        ;read 2nd char 
    mov ah, 0x03 
    int 0x10 
    add dl, 1 
    int 0x10 
    mov ah, 0x08 
    int 0x10 
    mov bl, al 
    pop bx 
        ;read 3rd char 
    mov ah, 0x03 
    int 0x10 
    add dl, 1 
    int 0x10 
    mov ah, 0x08 
    int 0x10 
    mov bl, al 
    pop bx 
        ;try to write all 3 chars 
    call newline 
    mov si, write_attempt 
    call print 
    call newline 
    push bx 
    mov al, bl 
    call printchar 
    push bx 
    mov al, bl 
    call printchar 
    push bx 
    mov al, bl 
    call printchar 
    call newline 
    mov si, read_write_success 
    call print 
    call newline 
    ret 

S'il vous plaît garder à l'esprit que tout avant le « deuxième secteur » a été écrit comme il y a 2 mois et tout ce qui suit a été écrit au cours des 2 derniers jours. J'utilise également NASM pour assembler le code.

Voici une image de ce qu'il fait imgur

+0

Je ne pense pas que 10h, ah = 08h fait ce que vous pensez. Je vous suggère de lire sur int 10h et ensuite décrire plus en détail ce que vous essayez de faire. – prl

+0

faire 10h int et ah = 08h devrait "Lire le caractère et l'attribut à la position du curseur" et placez le char dans tout ce que je peux faire un bl mov, al et le pousser dans une pile pour une utilisation ultérieure – Psaidiwd

+0

quel caractère est à la position du curseur? Aussi, à quoi servent les autres appels int 10h? – prl

Répondre

2

Vous imprimez du texte à l'écran et vous essayez ensuite de lire les 3 premiers caractères de ce texte à l'écran. Droite?

Il est bon d'utiliser la fonction BIOS 08h à cet effet, mais vous oubliez de positionner le curseur à chaque fois!

call newline 
mov si, read_attempt 
call print 
call newline ;(*) 

Cela a juste un texte de sortie en laissant le curseur ci-dessous son premier caractère.
Pour connaître la ligne, vous devez utiliser la fonction BIOS 03h, puis remonter d'une ligne.
Vous avez seulement besoin de spécifier la page d'affichage en BH une fois que vous n'utilisez pas le registre BH pour autre chose!
Important: n'oubliez pas de spécifier les numéros de fonction.

mov bh, 0  ;Select display page 0 
mov ah, 03h ;BIOS.GetCursor -> CL, CH, DL, DH 
int 10h 

dec dh   ;Go 1 row up, Column is at 0 because of (*) 
mov ah, 02h ;BIOS.SetCursor 
int 10h 

mov ah, 08h ;BIOS.ReadCharacterAndAttribute -> AL, AH 
int 10h 
push ax   ;Save 1st character on stack 

Pas besoin de relire la position du curseur, car les DL et DH registres contiennent toujours la position. Il suffit d'incrémenter la colonne DL et mettez-le par le BIOS:

inc dl   ;Go 1 column right 
mov ah, 02h ;BIOS.SetCursor 
int 10h 

mov ah, 08h ;BIOS.ReadCharacterAndAttribute -> AL, AH 
int 10h 
push ax   ;Save 2nd character on stack 

Répétez l'opération pour le 3ème caractère:

inc dl   ;Go 1 column right 
mov ah, 02h ;BIOS.SetCursor 
int 10h 

mov ah, 08h ;BIOS.ReadCharacterAndAttribute -> AL, AH 
int 10h 
push ax   ;Save 3rd character on stack 

Pour imprimer utilisation:

pop ax   ;Restore 3rd character 
call printchar 
pop ax   ;Restore 2nd character 
call printchar 
pop ax   ;Restore 1st character 
call printchar 

En raison de la façon dont les caractères de la pile seront affichés dans l'ordre inverse .
Si la commande est importante, commencez à lire sur l'écran au 3e caractère et travaillez vers le début.

mov bh, 0  ;Select display page 0 
mov ah, 03h ;BIOS.GetCursor -> CL, CH, DL, DH 
int 10h 
MOV DL, 2  ;START AT 3RD CHARACTER 
dec dh   ;Go 1 row up 
mov ah, 02h ;BIOS.SetCursor 
int 10h 
mov ah, 08h ;BIOS.ReadCharacterAndAttribute -> AL, AH 
int 10h 
push ax   ;Save 3rd character on stack 
DEC DL   ;GO 1 COLUMN LEFT 
mov ah, 02h ;BIOS.SetCursor 
int 10h 
mov ah, 08h ;BIOS.ReadCharacterAndAttribute -> AL, AH 
int 10h 
push ax   ;Save 2nd character on stack 
DEC DL   ;GO 1 COLUMN LEFT 
mov ah, 02h ;BIOS.SetCursor 
int 10h 
mov ah, 08h ;BIOS.ReadCharacterAndAttribute -> AL, AH 
int 10h 
push ax   ;Save 1st character on stack 
... 
pop ax   ;Restore 1st character 
call printchar 
pop ax   ;Restore 2nd character 
call printchar 
pop ax   ;Restore 3rd character 
call printchar 
+1

La position du curseur BIOS est basée sur zéro. Le 3ème caractère est donc 'DL = 2'. – Fifoernik

2

Vous utilisez pousser où vous dire pop et vice versa. Push enregistre une valeur sur la pile et pop récupère une valeur de la pile. Donc, la façon dont le code est écrit, il imprime la valeur en bl trois fois. Il gâche également l'adresse de retour sur la pile. Assurez-vous que vos poussées et vos coups sont équilibrés.

+0

donc j'ai inversé les pops et les pousse et maintenant ça n'imprime rien – Psaidiwd