2009-08-19 11 views
3

J'apprends actuellement l'assemblage Windows/DOS. Je fais juste un petit programme qui ajoute deux entiers de base 10, et sort la solution à la sortie standard. Voici mon code actuel:Windows/DOS Assembly - Simple Math

org 100h 


MOV al,5 
ADD al,3 

mov dx,al 

mov ah,9 
int 21h 

ret 

Je suis confus quant à pourquoi quand cela est compilé, je reçois l'erreur:

erreur: combinaison non valide de opérandes et opcode

Parce que, théoriquement, tout Je suis en train de mettre 5 dans le registre AL, en ajoutant trois, en prenant le contenu du registre AL et en le mettant dans le registre DX pour la sortie, puis en l'affichant.

Toute aide serait appréciée, merci!

Répondre

7

DX est un registre de 16 bits, mais AL est un 8 bits.

charge AL dans DL et mis DH à 0.

Mais ça ne va pas ce que vous voulez; La fonction 9 [affiche une chaîne terminée par un zéro]. Vous lui dites d'afficher une chaîne qui commence à l'offset 9 du segment de données, ce qui va probablement être garbage.

Vous devrez convertir votre réponse en une série de chiffres d'abord, puis appelez la fonction 9.

Il y a quelques exemples de code pour converting the contents of a register to a string disponible. Copié ici pour référence, écrit par un utilisateur avec l'alias Bitdog.

; ------ WDDD = Write a Decimal Digit Dword at the cursor & a CRLF ------ 
; 
; Call with, DX:AX = Dword value to print 
; Returns, CF set on error, if DX:AX > 655359 max# 
;  (see WDECEAX.inc for larger number prints) 
align 16 
WDDD: CMP DX,10 
    JB WDDDok 
    STC  ;CF=set 
    RET  ;error DX:AX exceeded max value 
WDDDok: PUSH AX 
    PUSH BX 
    PUSH CX 
    PUSH DX 
    XOR CX,CX ; clear count register for push count 
    MOV BX,10 
WDDDnz: DIV BX ; divide DX:AX by BX=10 
    PUSH DX ; put least siginificant number (remainder) on stack 
    XOR DX,DX ; clear remainder reciever for next divide 
    OR AX,AX ; check to see if AX=number is divided to 0 yet 
    LOOPNE WDDDnz ; get another digit? count the pushes 
    MOV AH,2 ; function 2 for interupt 21h write digit 
    NEG CX ; two's compliment, reverse CX 
    MOV BL,48 ; '0' 
WDDDwr: POP DX ; get digit to print, last pushed=most significant 
    ADD DL,BL ; convert remainder to ASCII character 
    INT 21h ; print ascii interupt 21h (function 2 in AH) 
    LOOP WDDDwr ; deincrement CX, write another, if CX=0 we done 
    MOV DL,13 ; CR carriage return (AH=2 still) 
    INT 21h 
    MOV DL,10 ; LF line feed 
    INT 21h 
    POP DX 
    POP CX 
    POP BX 
    POP AX 
    CLC  ;CF=clear, sucess 
    RET 

; A divide error occurs if DX has any value 
; when DIV trys to put the remainder into it 
; after the DIVide is completed. 
; So, DX:AX can be a larger number if the divisor is a larger number.