assembly - 如何在 ARM 程序集的自定义函数中使用 while 循环(或任何循环)?
问题描述
我正在尝试解决一个问题,我有一个从 10 到 50 的计数器。对于每个数字,我必须检查它是否是 8 的倍数(如果是,那么我将 0xffff 存储在 R3 中),或者它是否是3 的倍数(我将存储 0xbbbb)或者如果它是两者的倍数(我将 0xffbb 存储在 R3 中)。
为了检查数字是否是 3 的倍数,我的计划是从数字中减去 3,直到它达到 0 或小于 3。我正在努力弄清楚如何在自定义函数中使用循环。到目前为止,这是我的代码:
.section .data
.balign 4
return_start: .word 0
.balign 4
return_loop: .word 0
.balign 4
return_8: .word 0
.balign 4
return_3: .word 0
.balign 4
return_3loop: .word 0
.section .text
.global _start
/* .func _loop
.func _multOf8
.func _multOf3 */
_start:
LDR R1, addr_return_start
STR lr, [R1]
mov r0, #10 /* Start with 10 */
BL _loop
LDR lr, addr_return_start
LDR lr, [LR]
_loop:
add R0, #1 /* increment by 1 */
MOV r3, #0 /* resetting r3 */
CMP R0, #50 /* check if it is 50, if it is then go to the end */
BEQ _end
/* else check if it is a multple of 8 */
BL _multOf8
/* check if it is a multiple of 3 */
BL _multOf3
B _loop
_multOf8:
/* save LR */
LDR R1, addr_return_8
STR lr, [R1]
AND r1, r0, #7
CMP r1, #0
MOVEQ r3, #0xffff /* if it is a multiple of 8 */
/* else return */
LDR LR, addr_return_8
LDR LR, [LR]
BX LR
_multOf3:
LDR R1, addr_return_3
STR lr, [R1]
/* if it is a multiple of 3 */
/* will need to subtract it continuously? */
PUSH R0
BL _3loop
POP R0
LDR LR, addr_return_3
LDR LR, [lr]
BX lr
_3loop:
LDR R1, addr_return_3loop
STR lr, [R1]
_end: B _end
addr_return_start: .word return_start
addr_return_loop: .word return_loop
addr_return_8: .word return_8
addr_return_3: .word return_3
addr_return_3loop: .word return_3loop
如您所见,在_multOf3
我试图分支到_3loop
. 问题是,我不知道如何处理LR
以及如何从这个循环中返回。我觉得如果我要存储 LR,每次我们遍历循环时都会不断地覆盖它。
任何帮助将非常感激!请注意,我是 ARM 汇编的初学者。
解决方案
ARM 中的循环并不太复杂。有几种方法可以实现一个。通常,您需要留出一个寄存器作为循环计数器。下面的例子是一个递减循环。
_loop: /* R2 is the loop counter */
/* do stuff here */
subs R2,R2,#1 /* the S at the end sets the flags accordingly. If the result is zero,
the zero flag will be set and BNE will not branch.
BNE _loop
/* if R2 = 0, execution will fall through to here, otherwise it jumps back to the loop's start
递增循环需要额外的步骤,因为您需要将循环计数器的值与所需的端点进行比较:
_loop /* R2 is the loop counter */
/* do stuff here */
add R2,R2,#1 /* no need for S at the end, it does us no good here. */
CMP R2,#50 /* 50 was arbitrarily chosen for this example. */
BNE _loop /* this just checks if they're not equal, for this example it's sufficient but
it's better to use BLS for signed numbers or BLO/BCC for unsigned */
推荐阅读
- wordpress - 清除重写规则wordpress
- json - 从 .Net Core 2.1 Web API 中的 JSON DateTime 响应中删除时间组件
- eclipse - Processing 3.3.7 - 在 Eclipse 中使用 processing.io,但没有 io.jar
- hadoop - MapReduce 作业未在 HADOOP 2.6.0(多节点集群)上运行
- azure - Azure 函数负载测试 VSTS
- javascript - Angular 2:如何使用路由器传播 HTML 元素?
- javascript - 您如何保存随机生成的数字的值以在不同的函数中调用?
- javascript - 如何在本机反应中动态地打开行(leftSwipe)
- amazon-web-services - 如何从 Auto Scaling Group 获取最不繁忙的 EC2 实例?
- hibernate - Hibernate 繁重的编辑会话