[英]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.