应用BEDMAS原理在汇编中计算7 * (4 + 10) + (15 / 5)

问题描述 投票:0回答:1

我正在尝试计算汇编中的表达式:

7 * (4 + 10) + (15 / 5)
。我假设 BEDMAS 原则仍然适用,但我运行的代码没有给我正确的数值。
我不确定我哪里出错了。当我们调用
DIV
时,它不会自动除以
AX
寄存器中的值吗?

MOV BX,10
ADD BX,4
MOV AX,15
MOV BL,5
DIV BL
ADD AX,BX
MOV BX, 7
MUL BX
HLT
assembly expression x86-16 operator-precedence emu8086
1个回答
0
投票

当我们调用

DIV
时,它不会自动除以
AX
寄存器中的值吗?

中,有一个 byte 大小的分区和一个 word 大小的分区。

  • 字节大小的
    div
    将 AX 除以您提供的任何字节大小的源操作数,例如。
    div bl
    。商归入 AL,余数归入 AH。
  • 字大小的
    div
    将 DX:AX 除以您提供的任何字大小的源操作数,例如。
    div bx
    。商归入 AX,余数归入 DX。

因此,在

MOV AX,15
MOV BL,5
DIV BL
中,您正在执行完美的字节大小除法。事实是,通过用除法器 5 加载 BL,您破坏了之前存储在 BX 寄存器中的总和 10 + 4。请记住,BL 不是一个单独的寄存器:它是我们给 BX 寄存器的最低 8 位起的名称。 BH 也是如此,BH 是我们给 BX 寄存器的最高 8 位起的名字。类似的规则适用于以下 16 位寄存器:AX、BX、CX 和 DX。

MOV BX,10
ADD BX,4
MOV AX,15
MOV BL,5
DIV BL
ADD AX,BX         <<<< Forgot to zero AH beforehand (i)
MOV BX, 7
MUL BX            <<<< Needlessly clobbers DX (ii)

(i) 幸运的是 AH 中的余数为零,但一般来说,您应该扩展 AL 中的商以覆盖整个 AX 寄存器。
(ii) DX clobber 的存在是因为在 中存在 byte 大小和 word 大小的乘法。

  • 字节大小的
    mul
    将 AL 乘以您提供的任何字节大小的源操作数,例如。
    mul bl
    。产品转到 AX。
  • 字大小的
    mul
    将 AX 乘以您提供的任何字大小的源操作数,例如。
    mul bx
    。产品转到 DX:AX。

除了上面提到的“缺陷”之外,这个计算不遵循正常的代数规则
您已计算出 7 * ( (4 + 10) + (15 / 5) ),而任务要求 ( 7 * (4 + 10) ) + (15 / 5)

将 BEDMAS 应用于
7 * (4 + 10) + (15 / 5)

B球拍是第一位的。而且由于这两组括号位于同一级别(它们不相互嵌套),因此我们计算它们的值的顺序并不重要。因为我们知道字节大小的除法仅在 AX 上运行,所以我们正在仔细选择其他一些寄存器来保存总和:

; (4 + 10) then (15 / 5)          ; (15 / 5) then (4 + 10)
mov  bl, 4                        mov  ax, 15
add  bl, 10   ; -> BL=14          mov  cl, 5
mov  ax, 15                       div  cl       ; -> AL=3
mov  cl, 5                        mov  bl, 4
div  cl       ; -> AL=3           add  bl, 10   ; -> BL=14

我们可以替换这些值并继续下一步。

将 BEDMAS 应用于
7 * 14 + 3

M乘法必须在A加法之前,并且由于字节大小的乘法在架构上使用 AL 寄存器,因此我们必须首先将当前在 AL 中的值 3 复制到另一个寄存器:

          mov  cl, al   ; Free AL, making CL=3
          mov  al, 7
          mul  bl       ; BL=14  -> AX=98
          add  al, cl   ; CL=3   -> AL=101

想要更大吗?

如果参与的数字更大,则可能需要一个字大小的解决方案。然后我们需要预先将 DX 寄存器清零,因为字大小的除法实际上将 DX:AX 除以字大小的操作数:

; (4 + 10) then (15 / 5)          ; (15 / 5) then (4 + 10)
xor  dx, dx                       xor  dx, dx
mov  bx, 4                        mov  ax, 15
add  bx, 10   ; -> BX=14          mov  cx, 5
mov  ax, 15                       div  cx       ; -> AX=3
mov  cx, 5                        mov  bx, 4
div  cx       ; -> AX=3           add  bx, 10   ; -> BX=14

由于字长乘法在架构上使用 AX 寄存器,因此我们必须首先将 AX 中当前的值 3 复制到另一个寄存器:

          mov  cx, ax   ; Free AX, making CX=3
          mov  ax, 7
          mul  bx       ; BX=14  -> DX:AX=98
          add  ax, cx   ; CX=3   -> AX=101
© www.soinside.com 2019 - 2024. All rights reserved.