2016-10-24 1 views
0

Oh boy ... Où est-ce que je commence même? J'ai essayé COUNTLESS fois pour obtenir un programme simple qui calcule la superficie d'une boîte (en seulement 4 étapes de multiplication ou moins) et retourne la superficie totale. J'ai essayé de définir le programme avec les variables principales étant des mots, et puis encore être des octets. mais peu importe, je reçois toujours une réponse qui ne correspond pas. mon programme ne contient pas d'erreurs ou d'avertissements, donc c'est un bon signe jusqu'à présent. J'ai essayé la multiplication signée et non signée, mais rien ne semble fonctionner. Je ne peux pas utiliser des mots doubles malheureusement que je n'ai pas le bon logiciel qui suit est mon programme:Multiplier les mots dans un programme de langue assemmbly semble correct, mais ne renvoie pas les bonnes réponses

INCLUDE io.h 

Cr  EQU 0DH  ; carriage return 
Lf  EQU 0AH  ; line feed 

TheStack SEGMENT STACK 
      DW 100H DUP (?) 
TheStack ENDS 

Data  SEGMENT 
a  Dw ? 
b  Dw ? 
c  Dw ? 
d   Dw ? 
f   Dw ? 
g   Dw ? 
h   Dw ? 
e  dw '2' 
Int1  db 6 DUP (?), 0 
Int2  db 6 DUP (?), 0 
SUM  Db 6 DUP (?), 0 
Int3  Db 6 DUP (?), 0 
Prompt1 DB 'Please enter the height: ', 0 
Prompt2 DB Cr, Lf, 'Enter the width: ', 0 
Prompt3 DB Cr, Lf, 'Enter the length: ', 0 
String DB 40 DUP (?) 
Label1 DB Cr, Lf, 'The sum is ' 
result1 DB 10 DUP (?), 0 

Data  ENDS 

Code  SEGMENT 
      ASSUME Cs:Code, Ds:Data 

Start: Mov Ax, SEG Data ; Load Data Segment Number. 
      Mov Ds, Ax 

Prompt: Output Prompt1  ; Prompt for first number. 
      Inputs String, 40 ; Read the ASCII characters. 
      AToI String   ; Convert ASCII to Integer. 
      Mov a, ax; Store first number. 
      Output Prompt2  ; Prompt for second number. 
      Inputs String, 40 
      AToI String 
      Mov b, dx ; Store second number. 
      Mul dx; Add second number. 
     mov d, ax 
     itoa result1, ax 
     output result1 
      Output Prompt3 
     Inputs String, 40 
      AToI String 
      Mov c, Dx ; Store second number 
     Mul dx; Add second number. 
     mov f, dx 
     output f 
     Mov b, dx 
     Mov c, ax 
     mul dx 
     mov g, ax 
     ATOI g 
      mov g, ax 
     ATOI f 
      mov f, ax 
     ATOI d 
      mov d, ax 
     add ax, f 
     add ax, g 
     mov h, ax 
     output h 
     AToI e 
     mov e, ax 
     mov h, dx 
     mul dx 
     itoa result1, ax 
     output result1 


Quit:  Mov Al, 0   ; Put return code of zero in Al. 
      Mov Ah, 4CH   ; Put DOS function call in Ah. 
      int 21H    ; Call DOS 

Code  ENDS 
      END Start 

Je vous présente mes excuses pour les mauvaises explications dans le code comme je l'ai copié le jist de celui-ci de précédent programme. maintenant ce que je ne comprends pas, c'est comment certaines variables parfaitement définies peuvent renvoyer des valeurs incorrectes. J'ai même changé les variables, mais je n'ai toujours pas eu de chance. C'est à la fois confus et ennuyeux. Pour le mettre en perspective, quand j'essaie de multiplier 1 fois 1, la valeur retournée est 402, ce qui est loin! Je suis nouveau à la programmation en montage, donc je crois que cela est dû en partie à l'inexpérience. Ma question est de savoir comment ce programme sans erreurs finit par retourner des valeurs erronées quand il est apparemment mis en place correctement et vérifié à plusieurs reprises pour des erreurs? Y a-t-il une pièce manquante? Ai-je besoin de le réécrire entièrement? Est-ce la faute de l'émulateur? Qu'est-ce qui ne va pas avec le code qui cause ce qui semble être un programme parfait pour ne pas fonctionner correctement?

+1

Utilisez un débogueur afin de pouvoir le parcourir et d'examiner les registres/la mémoire. Est-ce que vos fonctions 'ATOI',' itoa' ou 'output' sauvegardent/restaurent DX? Je pense que je vois au moins un cas où vous utilisez DX juste après avoir appelé 'output'. Dans la plupart des conventions d'appel, DX n'est pas conservé par appel. Vous ne montrez pas de code pour eux, ou ne dites pas de quelle bibliothèque ils proviennent. –

+0

Si votre programme ne lit que deux chiffres de l'utilisateur, pourquoi appelle-t-il plus de deux fois ATOI? Convertissez tout en nombre entier juste après l'avoir lu. Ensuite, vous pouvez garder des choses dans les registres sans un tas d'appels de fonctions et de charges/magasins entre vos maths. (Sur une CPU moderne, un aller-retour magasin/rechargement prend environ 5 cycles, ce qui est plus qu'une multiplication.) Prendre en compte le nombre de multiplications est fondamentalement peu pertinent par rapport à la quantité de choses que fait ce code: P) –

+1

que la multiplication de deux valeurs de 16 bits renvoie une valeur de 32 bits et la multiplication de deux valeurs de 8 bits renvoie une valeur de 16 bits? Vous devriez probablement regarder de plus près la documentation de 'MUL' et' IMUL' et vous assurer que vous ne laissez pas de données par inadvertance. –

Répondre

0

ce que je vois, une boîte a 6 côtés, deux de chaque sont de taille égale:

2 carrés x par y
deux carrés x par z
2 carrés de y par z
de la surface de la boîte est la somme de tous

tout ce que vous devez est:

magasin les longueurs entrées à [side_x], à [side_x] et [side_z]. Ensuite, le calcul de la somme de toutes les 3 paires de carrés pourrait ressembler à ceci (il est tout sauf optimisé)

start: mov ax,[side_x]   ; side x*y 
     mov bx,[side_y] 
     mov dx,0 
     mul bx 
     shl ax,1     ; 2 times 
     mov [box_size],ax 

     ; + 2 sides x*z 
     mov ax,[side_x]   
     mov bx,[side_z] 
     mov dx,0 
     mul bx 
     shl ax,1 
     add ax,[box_size] 
     mov [box_size],ax 

     ; + 2 sides y*z 
     mov ax,[side_y]   
     mov bx,[side_z] 
     mov dx,0 
     mul bx 
     shl ax,1 
     add ax,[box_size] 
     mov [box_size],ax 

puis imprimer [box_size] et vous fait

Note: Bien sûr, cela ne Fonctionne lorsque la taille de la boîte correspond à un registre 16 bits (< 65536), donc la "partie supérieure" de la multiplication (en dx) est ignorée

+0

J'ai essayé et même après, je ne reçois toujours pas la bonne valeur retournée. Je suis supposé inviter l'utilisateur pour les tailles puis les multiplier. Je ne suis même pas sûr de ce que je fais mal! J'ai l'impression de courir en rond. –

+0

gratter cela, je l'ai juste essayé avec des variables prédéfinies et cela fonctionne. mais pas avec les variables que je veux être défini via l'invite. Étrange. Je me demande ce que je fais mal. –

+0

aha! J'ai découvert ce que j'avais mal fait! C'était juste sous mon nez! J'ai mis la troisième invite trop tôt. Maintenant, pourquoi est-ce que ça m'a manqué dans le monde? lol –