Algorithm 如何在ARM组装中实现除法算法?
我试图在ARM assembly中实现以下算法,但当我在ARMSim 1.9.1中运行代码时,它会完全不变地打印出商和余数(本例中为0和5)。有人能告诉我我做错了什么吗?我想这可能就是我试图设置寄存器最右边位的地方Algorithm 如何在ARM组装中实现除法算法?,algorithm,assembly,arm,division,Algorithm,Assembly,Arm,Division,我试图在ARM assembly中实现以下算法,但当我在ARMSim 1.9.1中运行代码时,它会完全不变地打印出商和余数(本例中为0和5)。有人能告诉我我做错了什么吗?我想这可能就是我试图设置寄存器最右边位的地方 Given: Two positive integers: a Divisor X, and a Dividend Y Use three General Purpose Registers (R, Q, X) where R stores the Remainder, Q stor
Given: Two positive integers: a Divisor X, and a Dividend Y
Use three General Purpose Registers (R, Q, X)
where R stores the Remainder, Q stores the Quotient, and X stores the Divisor.
Steps:
1. Copy Y into the Remainder register (R)
Register Q will be initialized as 0
2. update: R = R - X
3. If R >= 0 then
Shift the Quotient Register (Q) to the left (1 bit)
and set the new rightmost bit to 1
Else
Restore the original value by of R: R = R + X
Also, Shift the Quotient Register (Q) to the left (1 bit)
and set the new least significant bit to 0
4. Shift the Divisor Register (X) to the right (1 bit)
5. Repeat 31 more times
这是我的代码:
.equ X, 12 @ the divisor - change to whatever number you wish
.equ Y, 5 @ the dividend - change to whatever number you wish
.global main
main:
LDR R6, =Y @ R6 = R = Y
MOV R7, #0 @ R7 = Q = 0
MOV R8, #0 @ R8 = count = 0
LDR R9, =X @ R9 = X
loop: SUB R6, R6, R9 @ R -= X
CMP R6, #0 @ if R >= 0
BGE _if @ goto _if
CMP R6, #0 @ else if R < 0
BLT _else @ else goto _else
ADD R8, R8, #01 @ count++
MOV R9, R9, LSR #01 @ shift X right 1 bit
CMP R8, #32 @ if count <= 32
BLE loop @ continue looping
_if:
MOV R7, R7, LSL #01 @ shift Q left 1 bit
ORR R7, R7, #01 @ set rightmost bit to 1
_else:
ADD R6, R6, R9 @ R += X
MOV R7, R7, LSL #01 @ shift Q left 1 bit
AND R7, R7, #2147483646 @ set rightmost bit to 0
exit:
MOV R1, R7 @ R1 = Q
SWI 0x6B @ cout << R1
MOV R1, R6 @ R1 = R
SWI 0x6B @ cout << R1
SWI 0x11 @ exit
.eq X,12@除数-更改为您想要的任何数字
.equ Y,5@股息-更改为您希望的任何数字
.全球主要
主要内容:
LDR R6,=Y@R6=R=Y
MOV R7,#0@R7=Q=0
MOV R8,#0@R8=count=0
LDR R9,=X@R9=X
回路:子R6、R6、R9@R-=X
CMP R6,如果R>=0,则为0
BGE_if@goto_if
CMP R6,如果R<0,则为#0@else
BLT_else@else goto_else
加上R8,R8,#01@count++
MOV R9,R9,LSR#01@移位X右1位
CMP R8,#32@if count 5除以12应该得到Q=0
和R=5
。我看不出它在这里有什么意义,但“将最右边的位设置为0”会清除lsb和msb(即符号位)-只使用bic r7,r7,#1
比使用难以理解的十进制常量更好。此外,无需连续两次cmpr6、#0
——是否执行第一个分支不会影响标志的后续状态。不管怎样,考虑一下在你把这些分支中的一个转移到<代码>之后,如果或 >代码< >代码> -接下来执行什么?哇,我是个白痴。我混淆了除数和股息。非常感谢。我应该在if/else分支后使用BX LR返回调用函数吗?5除以12应该得到Q=0
和R=5
。我看不出它在这里有什么意义,但“将最右边的位设置为0”会清除lsb和msb(即符号位)-最好只使用bic r7,r7,#1
比难以捉摸的十进制常数还要多。此外,无需连续两次cmpr6、#0
——是否执行第一个分支不会影响标志的后续状态。不管怎样,考虑一下在你把这些分支中的一个转移到<代码>之后,如果 或 >代码< >代码> -接下来执行什么?哇,我是个白痴。我混淆了除数和股息。非常感谢。我应该在if/else分支之后使用BX-LR返回调用函数吗?