2009-08-19 34 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.