2015-11-06 25 views
0

我試圖將r0-r5傳遞給函數check。但是隻有寄存器r0-r3被引用複製。在我的主要功能,我有這個代碼。具有4個以上寄存器的函數調用ARM程序集

push {lr} 
    mov r0, #1 
    mov r1, #2 
    mov r2, #3 
    mov r3, #4 
    mov r4, #5 
    mov r5, #6 
    bl check 
    pop {lr} 
    bx lr 

在我的check功能我有這個代碼。這是在一個單獨的文件還不能肯定,如果該事項

m: .asciz "%d, %d ~ (%d, %d, %d) 
    ... 
    push {lr} 
    ldr r0, =m 
    bl printf 
    pop {lr} 
    bx lr 

這個輸出是2, 3 ~ (4, 33772, 1994545180)。我想學習大會,所以你可以請解釋一些谷歌搜索的答案我知道我需要使用堆棧,但是,我不知道如何使用它,並想學習如何。提前致謝。

+0

如果您不太熟悉所涉及的所有內容,可能會有點困難,但參考您可以找到EABI調用約定的官方定義[http://infocenter.arm.com /help/topic/com.arm.doc.ihi0042e/index.html)。 – Notlikethat

回答

1

你可能只是嘗試一下,看看

void check (unsigned int, unsigned int, unsigned int, unsigned int, unsigned int); 

void call_check (void) 
{ 
    check(1,2,3,4,5); 
} 

ARM-Linux的gnueabi-GCC -c -02 check.c -o check.o ARM-Linux的gnueabi-objdump的-D check.o

00000000 <call_check>: 
    0: e52de004 push {lr}  ; (str lr, [sp, #-4]!) 
    4: e3a03005 mov r3, #5 
    8: e24dd00c sub sp, sp, #12 
    c: e58d3000 str r3, [sp] 
    10: e3a00001 mov r0, #1 
    14: e3a01002 mov r1, #2 
    18: e3a02003 mov r2, #3 
    1c: e3a03004 mov r3, #4 
    20: ebfffffe bl 0 <check> 
    24: e28dd00c add sp, sp, #12 
    28: e8bd8000 ldmfd sp!, {pc} 

現在當然這可以手動優化,仍然可以正常工作。也許他們保持堆棧對齊在16字節/ 4字/ 64位邊界是額外的12字節修改堆棧指針的原因?不知道。但除此之外,你可以看到你自然需要保存鏈接寄存器,因爲你正在調用另一個函數。 r0 - r3是顯而易見的,然後根據eabi,堆棧中的第一件事就是參數的第5個字。

同樣對於你的檢查功能,你可以簡單地讓編譯器讓你開始。如果你看看你的代碼,r0會作爲你的第一個參數進來,然後通過將它改爲printf的第一個參數來清除它。你需要將6個參數傳遞給printf,你需要將它們移動到第一個參數上,以檢查是否爲printf的第二個參數,檢查的第二個參數是第三個到printf等等。所以代碼必須做這樣的轉換(其中兩個現在在堆棧中)。

相關問題