2016-09-09 1 views
0

Je cours DOSBox en utilisant l'utilitaire de débogage pour construire le code d'assemblage. J'essaie juste de comprendre comment lire dans une chaîne. J'ai ceci jusqu'ici.DOSBox Debug Assembly

-n test.com 
-a 
072A:0100 db 15 
072A:0101 db 16 
072A:0102 mov dx, 100 
072A:0105 mov ah, 0A 
072A:0107 int 21 
072A:0109 int 20 

-rcx 15 
-w 
-q 

Donc je peux lire dans une chaîne de caractères de 15 caractères ou moins à partir du tampon. Quand je lis dans la chaîne, où est-il placé? Je veux essayer d'imprimer la chaîne.

+0

Vous n'avez pas réservé 15 octets, vous avez réservé un octet à l'emplacement 100 qui contient un 15 et un autre à l'emplacement 101 qui contient un 16. Je suis assez sûr que vous voulez jeter un oeil à la 'DUP 'directive. –

+0

La question est un peu floue et trop large. Vous devriez réfléchir un peu plus dans votre squelette et affiner votre question à un certain point. –

+2

@DavidHoelzer: ne croyez pas que le débogage DOS supporte quelque chose comme DUP. Les étiquettes ne sont même pas supportées. –

Répondre

3

Le code de votre exemple a 2 problèmes.

Vous ne voulez pas placer vos données brutes au décalage 100 car le DOS va commencer l'exécution en commençant à cette adresse. Pour cette raison votre code commençant au décalage 102 ne s'exécutera pas correctement car il s'assemblera à l'instruction "ADC AX, BA16" qui vole l'octet BA de votre instruction "mov dx, 100" et le reste des instructions sera mal interprété . Si vous n'avez pas eu le problème n ° 1, le deuxième problème est que les caractères d'entrée écraseront votre code à partir du décalage 102 (puisque les deux premiers octets du tampon à 100 sont réservés). Si vous pouviez exécuter le code, ce n'est probablement pas ce que vous voulez. ;)

Vous ne voulez pas définir de données au décalage 100 car il s'agit du point d'entrée d'un programme .COM. Un moyen simple de gérer cela est de définir vos données après le code. Lors de l'utilisation de quelque chose comme le débogage où vous devez spécifier des emplacements de mémoire directement sans l'utilisation d'étiquettes, la taille des opérandes assemblés doit être prise en compte.

Une méthode consiste simplement à assembler votre code à partir de l'adresse 100 et à utiliser des espaces réservés pour vos adresses de chaîne et de tampon; puis corrigez ces instructions une fois que vous avez défini les données.

Voici votre échantillon révisé:

NOTE: Je ne pouvais pas me aider et a ajouté une invite sortie avant la fonction d'entrée de chaîne

-n test2.com 
-a 
0100: mov dx,100 ;100 is a placeholder for the address of output prompt 
0103: mov ah,9 
0105: int 21  ;output prompt 
0107: mov dx,100 ;100 is a placeholder for the address of the input buffer 
010A: mov ah,0a 
010C: int 21  ;read user input 
010E: int 20 
0110: db 48   ;"H" 
0111: db 65   ;"e" 
0112: db 6c   ;"l" 
0113: db 6c   ;"l" 
0114: db 6f   ;"o" 
0115: db 3a   ;":" 
0116: db 20   ;<space> 
0117: db 24   ;"$"/DOS strings terminated by dollar sign 
0118: db 0f   ;buffer member: hold 15 chars 
0119: db 00   ;buffer member: character input count stored here 

;the remainder of the .COM memory segment can be used to store the data 
; starting at address 11A 

;now that we know where our data fits, lets plug the addresses in 

-a 100 
0100: mov dx,110 ;address of "H" in prompt string 
-a 107 
0100: mov dx,118 ;address of input buffer with first two bytes reserved (see above) 
        ;max length to read and characters read 

-rcx 
CX 0000 
:1a 
-w 
Writing 001A bytes 

;lets run the program 

-g 
Hello: <lets assume you type "cat" followed by RETURN> 
Program terminated normally 

;now look at the 2nd byte in the buffer for the number of characters typed 
; along with the character data entered 

-d 118 11e 
0110   0F 03 63 61 74 0D 0D  ..cat.. 

Je ne pense pas que vous avez à vous soucier réserver de l'espace pour votre tampon une fois que vous avez défini le membre max des caractères d'entrée; Puisque le tampon est à la fin du programme, vous avez accès au reste du segment 64k comme espace tampon. (64k moins les 0x11b octets de code et l'espace d'environnement qui est).

EDIT 2016/09/11

Voici une version révisée (avec explication) pour répondre à vos questions sur ce qui a été sortie tapé par l'utilisateur:

0100 MOV  DX,0140 
0103 MOV  AH,09 
0105 INT  21   ;output prompt 
0107 MOV  DX,014B 
010A MOV  AH,0A 
010C INT  21   ;read user input 
010E MOV  DX,0148 
0111 MOV  AH,09 
0113 INT  21   ;output CRLF 
0115 MOV  DI,[014C]  ;load DI with value of characters read 
0119 AND  DI,00FF  ; MOV above read WORD, but we only want lower byte 
011D LEA  DI,[DI+014D] ;point DI to end of input string 
0121 MOV  AL,24   ;load DOS terminator char "$" in AL 
STOSB     ;write it to end input string 
0124 MOV  DX,014D 
0127 MOV  AH,09 
0129 INT  21   ;print the input string 
012B INT  20   ;exit program 

;I inserted NOPS until address 0140 so I would have room to insert code without my 
; data offsets changing 

0140 DB 48     ;"Hello: $" prompt begin 
0141 DB 65 
0142 DB 6C 
0143 DB 6C 
0144 DB 6F 
0145 DB 3A 
0146 DB 20 
0147 DB 24 
0148 DB 0D     ;CRLF$ sequence begin 
0149 DB 0A 
014A DB 24 
014B DB 20     ;Buffer begin (32 bytes max length) 
014C DB 00 

Il y a plusieurs façons de obtenir le même résultat, comme charger le registre CX avec le nombre d'entrées de l'utilisateur et utiliser une instruction LOOP pour imprimer chaque caractère en utilisant la fonction DOS appropriée. Bonne chance!

+0

Wow, ça a plus de sens! Je peux voir les personnages en mémoire, mais comment pourrais-je les mettre dans DL et les imprimer un par un. J'ai essayé d'utiliser 'mov DL, (emplacement de mémoire)' mais cela me donne une erreur. –

+0

Vous obtiendrez une erreur si vous n'entourez pas l'emplacement de mémoire entre parenthèses indiquant que vous souhaitez déplacer le contenu de la mémoire plutôt que l'adresse WORD elle-même qui ne peut pas entrer dans DL parce que DL est de taille octet. Aussi parce que debug.com ne supporte pas la syntaxe "BYTE PTR", vous devrez peut-être l'impliquer en utilisant "movsb" au lieu de "mov". Par exemple. "movsb dl, [11a]" – byteptr

+0

Parfait! Je n'ai pas fait ce genre de montage depuis des années. Ok, disons que ma chaîne se trouve à 115, donc le premier caractère est à '[117]'. ('mov DL, [117]') Si je fais un incrément à 'DL', il me donne simplement le caractère suivant dans l'alphabet. Comment puis-je incrémenter le caractère suivant dans la chaîne, c'est-à-dire '[118]'. –