Assembly 试图在手臂上分开得到奇怪的结果

Assembly 试图在手臂上分开得到奇怪的结果,assembly,arm,Assembly,Arm,我正在尝试在不使用ARM组件中的divide函数的情况下进行除法。我的代码如下。由于某种原因,结果一直保持在2400年代 我已尝试将以下伪代码写入arm: 在r0和r1中获取输入 将r1添加到r3,直到r3超过r0 增量计数器 从r3中减去r0得到余数 打印输出计数器和r3 ldr r3,=0 ldr r6,=0 next: bl getnum mov r5,r0 bl getnum mov

我正在尝试在不使用ARM组件中的divide函数的情况下进行除法。我的代码如下。由于某种原因,结果一直保持在2400年代

我已尝试将以下伪代码写入arm: 在r0和r1中获取输入 将r1添加到r3,直到r3超过r0 增量计数器 从r3中减去r0得到余数 打印输出计数器和r3

    ldr     r3,=0
    ldr     r6,=0

   next:
    bl      getnum
    mov     r5,r0
    bl      getnum
    mov     r6,r0

    mov     r0,r5
    mov     r1,r6


    bl      mydivide
    b       next






   mydivide:
    cmp     r3,r0
    bge     rem
    add     r3,r3,r1
    add     r6,#1
    b       mydivide




   rem:
    sub     r3,r0
    mov     r2,r3
    mov     r1,r6
    ldr     r0,=output
    bl      kprintf
 output:             .asciz"%dR%d\r\n"
预期: ? 100 ? 40 2R20

实际: ? 100 ? 40
40R2340

使用调试器单步执行程序并查看出错的地方。显然,您使用了
r6
作为计数器,但从未对其进行初始化。您使用r6同时保存两个不同的值,一个计数器和一个除数。我记得ARM的快速但复杂的除法算法没有除法指令。他们使用了两个256字节的表,一个用于商数<256,另一个用于种子算法来查找1/商数(有时会偏离+1,因此必须进行最后一次乘法后检查)。@rcgldr:可能基于硬件ALU除法器使用的相同基数算法?除了最小的商,任何东西都比重复减法好。e、 有一个一次一位的O(logn)算法,使用移位。我认为这可能是基数-16或更高的基数HW div/sqrt单元所做的最简单的情况。对于常数除数,当然还有乘法逆(让编译器为您计算常数很方便)@PeterCordes-有一个商<256的检查,如果是,使用一个表。如果不是的话,那就是牛顿·拉斐逊的一个变种,即得到1/除数,它使每次迭代的位数翻倍,从另一个表中的7位开始。进行4次乘法和一些加法和移位,得到28位,然后用一个分子乘以除数,再进行一次乘法得到余数,并检查除法是否需要增加商。