【问题标题】:Assembly multiply/divide menu汇编乘法/除法菜单
【发布时间】:2017-04-29 05:29:29
【问题描述】:

我对汇编编程很陌生,主要是想从 youtube 视频和“x86 处理器的汇编语言”pdf 中学习。该程序现在还没有接近完成,但我已经遇到了 3 个我无法弄清楚的错误。

  1. 文件中的无效字符(第 1 行)
  2. 无效的指令操作数(第 27、46、26 行)
  3. 符号类型冲突(第 15 行)

    .model small
    .data
    message db "Please enter a for mutiplication or b for division $"
    message2 db " Enter the first number $"
    message3 db " Enter the second number $"
    message4 db " * $"
    message5 db " / $"
    message6 db " = $"
    
    .code
    main proc
    mov ax, seg message
    mov ds, ax
    mov dx, offset message
    mov ah, 9h
    int 21h
    
    mov ah, 1h ;input stored in al
    int 21h
    
    mov bl, al ; menu selection input stored in bl so al can be used freely
    
    mov ah, seg message2
    mov ds, ah
    mov dx, offset message2
    mov ah, 9h
    int 21h
    
    mov ah, 1h; input stored in al
    int 21h
    
    mov cl, al ; first number input stored in cl so al can be used freely
    
    mov dl, bl
    mov ah, 2h
    int 21h
    
    mov dl, al ;second number imput stored in dl so al can be used again
    
    sub cl, 30h ;convert characters to decimal
    sub dl, 30h
    
    mov ax, cl ;preform division
    div dl
    
    mov al, cl ;preform multiplication
    mul dl
    
    
    add cl, 30h ; convert decimal back to the characters
    add dl, 30h
    
    
    
    main endp
    
     end main
    

最终我想将输入范围限制在 1-100 之间,我也很感激任何关于如何做到这一点的提示,任何帮助都将不胜感激

【问题讨论】:

  • 删除试图从message获取段的行。在代码顶部,您可以使用 mov ax, @data mov ds, ax 设置一次 DS
  • 不允许使用mov ax, cl 行。 CL 是 8 位寄存器,AX 是 16 位寄存器。
  • 当我现在使用“@data”时,它给了我一个新的错误“未定义的符号:Dgroup”与“@data”的行。我在这里想念什么?我需要使用 IsDefined 吗?
  • 你用什么来组装这个?你的链接器是什么?几乎听起来您的链接器可能无法理解 16 位。
  • 我正在使用 Microsoft Visual Studio 我打开了一个 win32 项目,其中构建自定义设置为 masm

标签: assembly x86 masm dos


【解决方案1】:

我无法在此处重现错误 1) 和 3)。也许他们已经“消失”了复制。删除源代码中的行并再次键入。

“错误A2070:无效指令操作数”:

1) 第 27 和 26 行:

mov ah, seg message2
mov ds, ah

段是一个 16 位的值。您不能将其加载到 8 位寄存器 (AH)。此外,您不能将 8 位寄存器 (AH) 复制到 16 位寄存器 (DS)。将这些行更改为:

mov ax, seg message2
mov ds, ax

2) 第 46 行:

mov ax, cl ;preform division
div dl

您不能将 8 位寄存器 (CL) 复制到 16 位寄存器 (AX)。执行此类操作有特殊说明:MOVZX & MOVSX。第一条指令将 8 位寄存器视为无符号整数,第二条指令将其视为有符号整数。将这些行更改为:

movzx ax, cl ;preform division
div dl

一种“古老的”8086方式是:

xor ch, ch ; set CH (the upper part of CX) to null
mov ax, cx ;preform division
div dl

【讨论】:

  • 天哪,我觉得自己很傻。感谢您的帮助,我在计划时考虑过使用 movzx 或 movsx 并完全忘记了。
  • @rkhb 我明白了。我已删除评论。
  • 如果你要异或零,请执行xor ax,ax / mov al, cl。这将cause partial-register stalls / slowdowns on fewer CPUs 比归零ch 然后读取cx。它的代码大小相同,并且应该在真正的 8086 上执行相同的操作。(在现代 CPU 上,在编写 al 之前对 eax 进行异或归零会比仅使用 ax 好得多)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-05-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多