【问题标题】:How to divide in assembly language using addition?如何使用加法在汇编语言中除法?
【发布时间】:2019-09-08 07:50:29
【问题描述】:

在高中的一门计算机工程课上,我们被分配了一项作业,我们必须通过加法过程用汇编语言将两个数字相除。

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

(编者注,教科书没有定义文本汇编语言,只有机器码操作码和操作数,用于这个带有 16 个 8 位寄存器和条件跳转指令的加载/存储机器。)

【问题讨论】:

  • 你能假设你的两个输入都是非负的(或者至少有相同的符号)吗?如果没有,您必须处理这种可能性并使用绝对值。除此之外,该算法在谷歌上很容易找到,例如Division returning quotient and remainder using a loop and subtraction?。更好的算法(O(log n) 而不是 O(n))是可能的,例如Implement division with bit-wise operator
  • @PeterCordes - 在这种情况下,复杂的事情是条件分支仅适用于寄存器 x == 寄存器 0,没有 或 >=。
  • @rcgldr:这是一个很好的观点。但是您可以使用AND + BNZ 来测试寄存器是否为负,因此如果您将范围限制为有符号值,则可以使用它。所以是的,对于留下余数的除法,检测结束是循环的重要部分,如do { quotient++; dividend += -divisor; } while( dividend >= 0 );
  • @PeterCordes - Martin Rosenau 在他的回答中涵盖了这一点。由于这些是 8 位寄存器,因此可以使用 3 个递增计数器(或根据需要递减负数)来缓慢完成。

标签: assembly binary cpu-architecture opcode


【解决方案1】:

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

如何使用加法来除...

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

; 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

玩具架构...具有 2 的补码加法和按位 AND/OR/XOR 运算...

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

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

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

但不能直接减法

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

  • 可以通过 XOR 操作将数字的所有位取反。
  • 请回忆一下如何对二进制补码中的数字取反。
  • 如果您能够对数字求反和相加,那么您也应该能够对数字进行减法。
  • 请回忆一下如何判断二进制补码是否为负数。
  • 如果您仅对 0...127 范围内的数字进行操作,则可以通过检查“(A-B) 是否为负”来检查“A 请注意,当您允许负输入时就是这种情况!
  • 如果您使用 0...255 的整个范围进行操作,则检查“A
  • 如果位 7 在 A 中为“1”而在 B 中为“0”,则 A
  • 如果位 7 在 A 中为“0”而在 B 中为“1”,则 A
  • 如果位 7 在 A 和 B 中具有相同的值(两位均为“0”或两位均为“1”),则可以检查“(A-B)是否为负”

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-01-22
    • 1970-01-01
    • 1970-01-01
    • 2016-02-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多