我有這個程式,我必須在 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 位的數字)我將 4bytes 添加到 r0 以進入陣列的下一個元素。之后,我從陣列長度中減去 1 以回圈遍歷陣列,直到其低于 0 以停止程式。我從我的測驗功能中得到的反饋是給我們檢查我們的程式是否作業的,它表明它部分作業。它說它適用于短陣列和長度為 0 的陣列,但不適用于長陣列。老實說,我迷路了。我想我犯了一個非常愚蠢的錯誤,但我找不到它,我' 我已經被這個簡單的問題困了 3 天了,但我嘗試過的一切都不起作用,或者正如我所說,只能“部分”起作用。如果有人可以幫助我,我將不勝感激。這是我得到的反饋:
- ? min 與其他數字一起使用
- ? min 適用于長陣列
- ? min 適用于短陣列
- ? 最小容忍大小 = 0
(x 代表“它不起作用”,? 代表“它起作用”)
所以你明白我在說什么嗎?我只是不明白如何實作它應該使用更長的陣列的事實。
uj5u.com熱心網友回復:
我不太擅長 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
uj5u.com熱心網友回復:
- 在 C 中編碼使用正確的型別
- 你不必遍歷從索引中
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
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/396815.html
上一篇:是否可以在分配中使用段暫存器?
