ARM无符号整数除法子程序

时间:2015-02-21 19:25:23

标签: assembly arm

我正在编写程序使用子程序DIVU进行无符号整数除法。 子程序将R1作为除数,将R0作为除数。只要除数不等于0,输出应该是R0剩余R1,进位标志为0.我的程序有问题,我想确保没有这个子程序行为不当的情况。我尝试过的每一个输入都给出了正确的输出,但是我想知道是否有人发现这个代码会有任何我看不到的问题。

 DIVU       PUSH    {R2} ;store R2 Value
            MOVS    R2,#0 ;move 0 to R2 for quotient
            CMP     R0,#0 ;Compare divisor to 0
            BEQ     SETCARRY    ;if divisor = 0 go to SETCARRY
WHILE       CMP     R1,R0       ;Compare R1 to R0
            BLT     ENDWHILE    ;if dividend<Divisor End loop
            ADDS    R2,R2,#1    ;Add 1 to quotient
            SUBS    R1,R1,R0    ;Dividend - divisor
            B       WHILE       ;branch to start of while
ENDWHILE    
            MOVS    R0,R2       ;move quotient to R0, so R0 remainder R1
            POP     {R2}        ;revert R2 to value before subroutine
            PUSH    {R0,R1}     ;push R0 and R1
            MRS     R0,APSR     ; Set C flag to 0
            MOVS    R1,#0x20    ; ""
            BICS    R0,R0,R1    ; ""
            MSR     APSR,R0     ; ""
            POP     {R0,R1}     ;revert R0 and R1 to answer
QUITDIV     BX      LR          ;Go back to program
SETCARRY    
            PUSH    {R0,R1}     ;Store R0 and R1
            MRS     R0,APSR     ; Set C flag to 1
            MOVS    R1,#0x20    ;""
            ORRS    R0,R0,R1    ;""
            MSR     APSR,R0     ;""
            POP     {R0,R1}     ; Revert R0 and R1 to answer
            B       QUITDIV     ;Go back to program

1 个答案:

答案 0 :(得分:1)

一个问题是,在除数为零的情况下,您永远不会pop r2,因此您最终会在r2中以可能意外的值返回,并且sp指向错误的地方。

另一种方式是,无论哪种方式你根本不接触进位标志 - 即APSR的第29位,而你的0x20掩码正在修改第5位(Thumb执行状态位),取决于你所处理的处理器模式,如果你试图将非零写回来,你可能会被忽略或者可能会产生不可预测的行为。

那就是说,你可以在修复它的同时摆脱一半的代码。在大多数架构版本中,您特别允许直接写入标志位,而不存在an immediate form of MSR存在的读 - 修改 - 写序列。因此,清除标志只是MSR APSR_nzcvq, #0的一种情况,单独设置进位标志将是MSR APSR_nzcvq, #0x20000000

相关问题