Windows/DOS 汇编 - 简单数学

发布于 2024-08-02 16:55:08 字数 304 浏览 2 评论 0原文

我目前正在学习 Windows/DOS 汇编。我只是编写一个小程序,将两个以 10 为基数的整数相加,并将解输出到标准输出。这是我当前的代码:

org 100h


MOV al,5
ADD al,3

mov dx,al

mov ah,9
int 21h

ret

我很困惑为什么编译时会出现错误:

错误:操作码和操作数的无效组合

因为理论上,我所做的就是将 5 放入 AL 寄存器,将 3 添加到将AL寄存器的内容放入DX寄存器输出,然后显示。

任何帮助将不胜感激,谢谢!

I'm currently learning Windows/DOS assembly. I'm just making a small program that adds two base 10 integers, and outputs the solution to standard output. Here is my current code:

org 100h


MOV al,5
ADD al,3

mov dx,al

mov ah,9
int 21h

ret

I'm confused as to why when that is compiled, I get the error:

error: invalid combination of opcode and operands

Because theoretically, all I'm doing is putting 5 into the AL register, adding three to it, taking the content of the AL register and putting it into the DX register for output, and then displaying it.

Any help would be appreciated, thanks!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

却一份温柔 2024-08-09 16:55:08

DX 是 16 位寄存器,而 AL 是 8 位寄存器。

AL 加载到 DL 中,并将 DH 设置为 0。

但这不会达到您想要的效果;函数 9 [显示以 null 结尾的字符串]。您告诉它显示一个从数据段偏移量 9 开始的字符串,这可能是垃圾。

您需要首先将答案转换为一系列数字,然后调用函数 9。

有一些示例代码 将寄存器的内容转换为可用的字符串。复制于此供参考,由别名为 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.

DX is a 16-bit register, but AL is an 8-bit.

Load AL into DL, and set DH to 0.

But that won't do what you want; function 9 [displays a null-terminated string]. You're telling it to display a string that starts at offset 9 of the data segment, which is probably going to be garbage.

You'll need to convert your answer into a series of digits first, and then call function 9.

There is some example code for converting the contents of a register to a string available. Copied here for reference, written by a user with the 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.
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文