2009-08-19 33 views
3

我目前正在學習Windows/DOS程序集。我只是製作一個小程序,添加兩個基本10位整數,並將解決方案輸出到標準輸出。這裏是我當前的代碼:Windows/DOS程序集 - 簡單數學

org 100h 


MOV al,5 
ADD al,3 

mov dx,al 

mov ah,9 
int 21h 

ret 

我很困惑,爲什麼被編譯的時候,我得到的錯誤:

錯誤:操作碼的組合無效和操作數

因爲從理論上說,所有的我正在做的是將5放入AL寄存器,增加3個,取出AL寄存器的內容並將其放入DX寄存器中輸出,然後顯示出來。

任何幫助將不勝感激,謝謝!

回答

7

DX是一個16位寄存器,但AL是一個8位。

負載ALDL,並設置DH爲0

但是,你想要什麼,不會做;函數9 [顯示一個以null結尾的字符串]。你告訴它顯示一個從數據段的偏移量9開始的字符串,這可能是垃圾。

你需要你的答案首先轉換成一系列數字,然後調用函數9

沒有爲converting the contents of a register to a string提供一些示例代碼。複製此處以供參考,由別名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.