2010-11-11 24 views
0

J'ai une question (apparemment) simple à lire dans une chaîne et je l'imprime à nouveau en utilisant l'assemblage basé sur l'interruption x86. Le problème que j'ai est d'accéder à la chaîne qui a été lue correctement. La variable - input db 20, 0, " " est ma chaîne initiale. Après que j'appelle l'interruption d'entrée, le 0 devrait maintenant tenir la longueur de la chaîne, que je dois stocker et passer à cx quand j'appelle l'interruption d'impression. 20 est la longueur maximale de l'entrée. Je me retrouve avec deux problèmes - comment puis-je accéder à la longueur de la chaîne (j'ai utilisé un nombre arbitraire, qui soit raccourcit ou imprime des ordures après la fin) et comment puis-je accéder à la chaîne sans le nombre de bits à la début? Toute aide appréciée, ma tentative:Problème d'accès aux variables d'assemblage basé sur les interruptions x86

(j'utilise tasm & TLink sous win 7 32 bits, ainsi que l'émulation de boîte dos)

;7. Read in a String of characters and Print the string back out. 


.model small 
.stack 100h 
.data 


    colour db 00001111b 
    input db 20, 0, "     " 
    strlen dw 20; this should be ? 


.code 

main: 

    call initsegs 
    call readstring 
    call printstring 
    call exit 



PROC printstring 

    push ax bx cx dx bp 

    mov ah, 13h ; int 13h of 10h, print a string 
    mov al, 1 ; write mode: colour on bl  
    mov bh, 0 ; video page zero 
    mov bl, colour; colour attribute 
    mov cx, strlen; getting this is the problem 
    mov dh, 10; row 
    mov dl, 10; column 
    mov bp, offset input ; es:bp needs to point at string..this points to string but includes its max and length at the start 

    int 10h; 


    pop bp dx cx bx ax 

    ret 

ENDP printstring 






PROC readstring 

    push ax dx 


    mov ah, 0ah ; function a of 21h - read a string 
    mov dx, offset input ; reads string into DS:DX so DX needs be offset of string variable 

    int 21h ; call the interrupt 
    ;mov strlen ....something 
    pop dx ax 

    ret 

ENDP readstring 



PROC exit 

    mov ah, 4ch 
    INT 21h 

    RET 

ENDP Exit 


PROC initsegs 

    push ax 

    mov ax, @DATA 
    mov ds, ax 
    mov es, ax 

    pop ax 

    RET 

ENDP initsegs 



end main 

Répondre

0

Ce que vous avez ici est connu comme Pascal String. La version originale (utilisée en langage Pascal 16bit) utilisé premier octet pour maintenir la longueur de la chaîne , et le reste des octets contaned la chaîne réelle (pas zéro terminé). Cela donne une longueur maximale de 255 octets.

La version utilise Delphi 32 bits utilisée approche différente slighly:

struct { 
    DWORD allocated_size; 
    DWORD used_size; 
    char* buff; 
}; 

Il est similaire à votre cas, mais vous utilisez BYTE pour la taille au lieu de DWORD. La méthode standard pour travailler avec eux est de garder le pointeur sur la chaîne de caractères réelle, et d'utiliser des décalages négatifs pour les champs spéciaux, comme dans:

lea ax, [input + 2] //; standard string, could need a trailing '\0' 
mov al, BYTE PTR [input+2 - 1] //; strlen 
mov al, BYTE PTR [input+2 - 2] //; allocated buff size 
0
inputBuffer LABEL BYTE 
maxChar  BYTE 10 
numinput BYTE ? 
buffer  BYTE 10 DUP (0) 
... 
    mov ah, 0Ah ; string input 
    mov dx, OFFSET inputBuffer 
    int 21h 

Mettez votre InputBuffer dans la section .data, cela fonctionne comme une structure qui est utilisée par l'interruption 21 (remplissage numinput avec le nombre de caractères read0