2009-08-19 3 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, добавляя три к нему, беря содержимое регистра AL и помещая его в регистр DX для вывода, а затем отображая его.

Любая помощь будет оценена, спасибо!

ответ

7

DX - это 16-разрядный регистр, но AL - это 8-разрядный.

нагрузки AL в DL и установите DH 0.

Но это не будет делать то, что вы хотите; function 9 [отображает строку с нулевым завершением]. Вы говорите, что он отображает строку, которая начинается со смещения 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. 
Смежные вопросы