[英]Finding the smallest element in array in arm assembly
我有这个程序,我必须在 arm 程序集中编写它来查找数组中的最小元素。 通常这在每种编程语言中都很容易做到,但我无法理解我在 arm 程序集中做错了什么。 我是 arm 的初学者,但我知道 c 的方式。 所以我写了关于如何在 c 中的数组中找到最小数字的算法,就像这样。
int minarray = arr[0];
for (int i =0; i < len; i++){
if (arr[i] < minarray){
minarray = arr[i];
}
这很容易,真的没什么特别的。 现在我尝试接管 arm 中的算法几乎相同。 有两件事从一开始就已经被编程。 第一个元素的地址存储在寄存器 r0 中。 数组的长度存储在寄存器 r1 中。 最后,最小的元素必须存储回寄存器 r0。 这是我所做的:
这与 c 中的算法几乎相同。 首先,我将第一个元素加载到新的寄存器 r4 中。 现在第一个元素是最小的。 然后再一次,我在 r8 中加载第一个元素。 我比较这两个,如果 r8 <= r4,则将 r8 的内容复制到 r4。 之后(因为我正在使用 32 位的数字)我将 4 字节添加到 r0 以进入数组的下一个元素。 之后,我从数组长度中减去 1 以循环遍历数组,直到其低于 0 以停止程序。 我从测试 function 中得到的反馈是为了检查我们的程序是否有效,这表明它部分有效。 它说它适用于长度为 0 的短 arrays 和 arrays 但不适用于长 arrays。 我真的迷路了。 我认为我犯了一个非常愚蠢的错误,但我找不到它,我已经被这个简单的问题困扰了 3 天,但我尝试过的一切都没有奏效,或者正如我所说,只能“部分”奏效。 如果有人可以帮助我,我将不胜感激。 这是我得到的反馈:
(x 表示“它不起作用”,✓ 表示“它起作用”)
所以你明白我在说什么吗? 我只是不明白如何实现它应该与更长的数组一起工作的事实。
我不太擅长 ARM 组装,据我了解,R4 有望保持最小值。 R8 用于保存从输入数组中获取的最新值。
使用此指令更新最小值:
MOVLE r8, r4
但它实际上更新了 R8,而不是 R4。
尝试:
MOVLE r4, r8
编辑
其他问题是使用不正确的分支指令:
SUBS r1, r1, #1
BPL loop1
像这样工作:
r1 = r1 - 1
if (r1 >= 0) goto loop1;
对于 R1 等于1
,循环执行两次。
r1 = 1
... do stuff
r1 = r1 - 1 // r1 is 0 now
if (r1 >= 0) goto loop1; // 0>=0 TRUE!
... do stuff, overflow the input by indexing at `[r0 + 4]`
r1 = r1 - 1 // r1 is -1
if (r1 >= 0) goto loop1; // -1 >= 0 FALSE
// exit function
要修复它,仅在输入非零时使用分支。
BNE loop1
0
迭代1
int foo(const int *arr, size_t len)
{
int minarray = arr[0];
for (size_t i = 1; i < len; i++)
{
if (arr[i] < minarray)
{
minarray = arr[i];
}
}
return minarray;
}
它生成以下代码:
foo:
mov r3, r0
subs r1, r1, #1
ldr r0, [r3], #4
beq .L1
.L3:
ldr r2, [r3], #4
cmp r0, r2
it ge
movge r0, r2
subs r1, r1, #1
bne .L3
.L1:
bx lr
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.