简体   繁体   English

在 arm 程序集中查找数组中的最小元素

[英]Finding the smallest element in array in arm assembly

I have this program that i have to write in arm assembly to find the smallest element in an array.我有这个程序,我必须在 arm 程序集中编写它来查找数组中的最小元素。 Normally this is a pretty easy thing to do in every programming language, but i just can't get my head around what i'm doing wrong in arm assembly.通常这在每种编程语言中都很容易做到,但我无法理解我在 arm 程序集中做错了什么。 I'm a beginner in arm but i know my way around c.我是 arm 的初学者,但我知道 c 的方式。 So I wrote the algorithm on how to find the smallest number in an array in c like this.所以我写了关于如何在 c 中的数组中找到最小数字的算法,就像这样。

int minarray = arr[0];
    for (int i =0; i < len; i++){
        if (arr[i] < minarray){
            minarray = arr[i];
        }

It's easy and nothing special really.这很容易,真的没什么特别的。 Now i tried taking over the algorithm in arm almost the same.现在我尝试接管 arm 中的算法几乎相同。 There are two things that have already been programmed from the beginning.有两件事从一开始就已经被编程。 The address of the first element is stored in register r0.第一个元素的地址存储在寄存器 r0 中。 The length of the array is stored in register r1.数组的长度存储在寄存器 r1 中。 In the end, the smallest element must be stored back in register r0.最后,最小的元素必须存储回寄存器 r0。 Here is what i did:这是我所做的:

This is almost the same algorithm as the one in c.这与 c 中的算法几乎相同。 First i load the first element into a new register r4.首先,我将第一个元素加载到新的寄存器 r4 中。 Now the first element is the smallest.现在第一个元素是最小的。 Then once again, i load the first element in r8.然后再一次,我在 r8 中加载第一个元素。 I compare those two, if r8 <= r4, then copy the content of r8 to r4.我比较这两个,如果 r8 <= r4,则将 r8 的内容复制到 r4。 After that (because i'm working with numbers of 32 bits) i add 4bytes to r0 to get on to the next element of the array.之后(因为我正在使用 32 位的数字)我将 4 字节添加到 r0 以进入数组的下一个元素。 After that i subtract 1 from the array length to loop through the array until its below 0 to stop the program.之后,我从数组长度中减去 1 以循环遍历数组,直到其低于 0 以停止程序。 The feedback i'm getting from my testing function that was given to us to check if our program works says that it works partly.我从测试 function 中得到的反馈是为了检查我们的程序是否有效,这表明它部分有效。 It says that it works for short arrays and arrays of length 0 but not for long arrays.它说它适用于长度为 0 的短 arrays 和 arrays 但不适用于长 arrays。 I'm honestly lost.我真的迷路了。 I think i'm making a really dumb mistake but i just cannot find it and i've been stuck at this easy problem for 3 days now but everything i have tried did not work or as i said, only worked "partly".我认为我犯了一个非常愚蠢的错误,但我找不到它,我已经被这个简单的问题困扰了 3 天,但我尝试过的一切都没有奏效,或者正如我所说,只能“部分”奏效。 I would really appreciate if someone could help me out.如果有人可以帮助我,我将不胜感激。 This is the feedback that i get:这是我得到的反馈:

  • ✗ min works with other numbers ✗ min 适用于其他数字
  • ✗ min works with a long array ✗ min 适用于长数组
  • ✓ min works with a short array ✓ min 适用于短数组
  • ✓ min tolerates size = 0 ✓ min 容忍 size = 0

(x is for "it does not work", ✓ is for "it works") (x 表示“它不起作用”,✓ 表示“它起作用”)

So you see what i'm saying?所以你明白我在说什么吗? i just do not understand how to implement the fact that its supposed to work with a longer array.我只是不明白如何实现它应该与更长的数组一起工作的事实。

I'm not very good at ARM assembly by to my understanding R4 is expected to keep the value of minimum.我不太擅长 ARM 组装,据我了解,R4 有望保持最小值。 R8 is used to keep the most recently fetched value from the input array. R8 用于保存从输入数组中获取的最新值。

The minimum is updated with this instruction:使用此指令更新最小值:

MOVLE   r8, r4

But it actually updated R8, not R4.但它实际上更新了 R8,而不是 R4。

Try:尝试:

MOVLE   r4, r8

EDIT编辑

Other issue is using incorrect branch instruction:其他问题是使用不正确的分支指令:

SUBS    r1, r1, #1 
BPL     loop1

works like:像这样工作:

r1 = r1 - 1
if (r1 >= 0) goto loop1;

For R1 equal to 1 the loop is exectured twice .对于 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

To fix it use branching only when input is non-zero.要修复它,仅在输入非零时使用分支。

BNE loop1
  1. Coding in C use the correct types C 中的编码使用正确的类型
  2. You do not have to iterate from the index 0 only 1您不必仅从索引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;
}

And it generates this code:它生成以下代码:

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.

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