2012-04-21 107 views
0

我被困在爲什麼這個函數在應該返回時反覆調用它自己。ARM函數沒有正確返回

Initialize: 
    stmfd sp!, {R0-R4,lr} 
    mov R4, #0 @used for storing 0 
    mov R0, #2 
    mov R5, #0 
    ldr R1, =sieve 
    ldr R1, [R1] 
    ldr R2, =primes 
    ldr R2, [R2] 
    str R4, [R1], #4 @intialize first and second elements in sieve to 0 
    str R4, [R1] 
    mov R4, #1 @used for storing 1 
setToOne: 
    str R4, [R1], #4 
    add R0, R0, #1 
    cmp R0, #MAX 
    blt setToOne 
    ldmfd sp!, {R0-R4,pc} @For somereason Initialize repeats as if lr points back to its begining (instead of where it's called from) 

好,因爲它說我不能發佈整個程序「您的文章沒有什麼太大的上下文解釋代碼段;請更清楚地解釋您的方案」

+0

我看不出爲什麼你的函數會重複調用自己的任何原因。你打電話過得怎麼樣? – 2012-04-21 10:40:27

+0

你能在ldmfd上設置一個斷點並看看你的棧嗎? (特別是堆疊的LR)。也許它會被粉碎(sieve相對於堆棧的位置,它的大小是多少?) - 假設你是一個「帶鏈接的分支」指令來調用「Initialize」(它在調用時更新LR) - 否則你的LR將毫無意義。 – Dan 2012-04-21 12:02:25

+0

是你的程序垃圾堆棧?什麼是反彙編(與地址等)和你的記憶地圖看起來像什麼 – 2012-04-21 14:31:25

回答

2

您正在覆蓋R5而未先保存。我不明白爲什麼它應該自己調用函數,但它可能會給出一些奇怪的結果。作爲一個方面說明,如果你從C調用這個函數,R0-R3不需要被保存,因爲它們是從頭寄存器。如果你從彙編中調用它,你當然可以創建你自己的調用約定,這可能需要保存它們。

+0

不,我試過保存R5,並沒有什麼區別。不過謝謝。 – Celeritas 2012-04-21 18:46:57

+0

奇怪的是,那是我可以看到可能出現的錯誤。函數如何被調用?你可以調試和破解,看看當你輸入函數時設置了什麼'lr'? – Leo 2012-04-21 20:02:28

+0

4100. **當我把斷點放在stmfd函數返回正確** – Celeritas 2012-04-22 04:30:23

0

我試着用MAX的幾個不同值的代碼,它工作正常:初始化 正在返回指令後面的指令(bl Initialize)。假設你正在做這個代碼片段之外的所有事情,罪魁禍首似乎是你的STR指令。您使用psedu ldr獲得了R1中sieve的值。篩選指向在沒有「填充」的情況下使用.skip時隱式初始化爲零的內存塊。現在您正在使用ldr R1, [R1],它在R1中加載了零,之後您正在執行一個str R4, [R1], #4,它正在清零地址ZERO處的單詞。現在我不知道你想要實現什麼樣的邏輯,但是如果我按照你的評論去做@in篩選sieve中的第一個和第二個元素爲0那麼你的代碼就沒有做你想做的事情。根據你在內存中安排你的代碼的方式,你可以用零覆蓋你自己代碼的一部分。 這可能是因爲你的Initialize處於零內存地址,你用零覆蓋堆棧上lr的值。我只是瘋狂地猜測。如果您提供了一些您正在嘗試實施的邏輯以及更多代碼的信息,那麼我可能會更好地爲您提供幫助。你可以嘗試的一件事是,一旦你完成了ldr R1, =sieve,將R1保留在你的STR中,並使用ldr R1, [R1]之類的其他寄存器來代替ldr R6, [R1]。根據您在呼叫者代碼中使用R6的方式,您可能會也可能不需要在堆棧上PUSH R6。這不是一個確切的答案,我想把它放在註釋部分,但我沒有足夠的權限來執行此操作。