2009-08-19 2 views
3

Ich lerne gerade Windows/DOS-Assembly. Ich mache nur ein kleines Programm, das zwei Basis 10 Ganzzahlen hinzufügt und die Lösung auf die Standardausgabe ausgibt. Hier ist meine aktuellen Code ist:Windows/DOS Assembly - Einfache Mathematik

org 100h 


MOV al,5 
ADD al,3 

mov dx,al 

mov ah,9 
int 21h 

ret 

Ich bin verwirrt, warum, wenn das kompiliert wird, erhalte ich die Fehlermeldung:

Fehler: ungültige Kombination von Opcode und Operanden

Weil theoretisch alle Ich mache 5 in das AL-Register, addiere drei dazu, nehme den Inhalt des AL-Registers und lege es in das DX-Register zur Ausgabe und zeige es dann an.

Jede Hilfe wäre willkommen, danke!

Antwort

7

DX ist ein 16-Bit-Register, aber AL ist ein 8-Bit.

laden AL in DL und setzen DH auf 0

Aber das wird nicht das tun, was Sie wollen; Funktion 9 [zeigt eine nullterminierte Zeichenfolge an]. Sie sagen, dass eine Zeichenfolge angezeigt werden soll, die bei Offset 9 des Datensegments beginnt, was wahrscheinlich Müll ist.

Sie werden Ihre Antwort in eine Reihe von Ziffern konvertieren müssen zuerst, und dann Funktion 9.

Es nennen, ist einige Beispiel-Code für converting the contents of a register to a string verfügbar. Kopiert hier zur Referenz, geschrieben von einem Benutzer mit dem 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.