如何使用加法在汇编语言中除法?

How to divide in assembly language using addition?

在高中的计算机工程class中,我们被分配了一个作业,我们必须使用加法过程用汇编语言除以 2 个数字。

我们正在为其编程的玩具架构没有除法指令。本机有2的补码加法和按位AND/OR/XOR运算,但没有直接减法:https://www.csie.ntu.edu.tw/~r03944025/intro2015/files/hw/appendix_c

(编者注,教科书没有定义文本汇编语言,只定义了机器代码操作码和这个load/store机器的操作数,有 16 个 8 位寄存器,和一个有条件的 jump-if-zero 指令.)

因为我不想做你的学校作业,所以我只会给你一些提示:

How to divide ... using addition?

这不是禁食法,但你可以这样做:

; Calculate C = A / B
Set C to 0
As long as A >= B:
    Increment C by 1
    Subtract B from A

如果 A 和 B 可能为负数,请执行以下操作:

Set D to 0
If A is negative:
    Set D to 1
    Negate A
If B is negative:
    Xor D with 1
    Negate B
Perform C = A / B (see above)
If D != 0:
    Negate C

The toy architecture ... has 2's complement addition and bitwise AND/OR/XOR operations ...

...和一个条件跳转指令,如果两个寄存器相等则跳转以及循环操作。

这非常重要,因为对于按位运算和加法,某些运算结果的位 0 仅取决于操作数的位 0。这意味着某些程序的最终输出的位 0 将仅取决于输入的位 0。

但是,对于 0x30 / 0x10 = 3 和 0x20 / 0x10 = 2 这两个除法,所有输入的位 0 为 0,但在一种情况下,输出的位 0 为 1,而在另一种情况下,输出的位 0输出为 0.

but not subtraction directly

关于您 CPU 没有的一些操作的一些提示:

  • 可以使用异或运算来反转数字的所有位。
  • 请回忆一下如何用二进制补码取反。
  • 如果你能取负数和加数,你应该也能减去数。
  • 请回忆一下如何判断二进制补码是否为负数。
  • 如果您仅使用 0...127 范围内的数字进行运算,则可以通过检查“(A-B) 是否为负数”来检查 "A<B"。
    请注意,当您允许负输入时就是这种情况!
  • 如果您使用整个范围 0...255,检查 "A<B" 会更困难:
    • 如果第 7 位在 A 中为“1”但在 B 中为“0”,则 A
    • 如果第 7 位在 A 中为“0”但在 B 中为“1”,则 A
    • 如果位7在A和B中具有相同的值(两位都为“0”或两位都为“1”),则可以完成“(A-B)为负”的检查