繁体   English   中英

ARM Unsigned Integer Division子例程

[英]ARM Unsigned Integer Division subroutine

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

 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

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

另一个是您根本不触摸进位标志的两种方式-APSR的第29位,而0x20掩码正在修改第5位(Thumb执行状态位),具体取决于您所处的处理器模式。如果您尝试向其写入非零值,则将被忽略或可能会产生不可预测的行为。

就是说,您可能会在修复它的同时摆脱一半的代码。 在大多数体系结构版本上,明确允许您直接写入标志位,而无需读取-修改-写入序列,对于该序列,存在立即形式的MSR 因此,清除标志只是MSR APSR_nzcvq, #0 ,而单独设置进位标志将是MSR APSR_nzcvq, #0x20000000

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM