我正在使用ARM程序集,我必須編寫一個子程序,我遵循ARM調用約定(這必須與某個單獨的更高級別實現集成其他)傳遞參數和返回值。現在,這是我在使用程序集時通常不確定的事情。在程序集中傳遞子程序的參數和返回值
所以根據約定,如果我理解得很好,參數將按順序從寄存器r0 - r4開始傳遞,然後使用其他參數堆棧。返回值傳遞給r0。
現在,這是我很困惑。如果我應該保存r0的上下文並在此之後彈出它,則無法返回結果,唯一的辦法是破壞第一個參數。有什麼解決方法嗎? 在此先感謝你們!
我正在使用ARM程序集,我必須編寫一個子程序,我遵循ARM調用約定(這必須與某個單獨的更高級別實現集成其他)傳遞參數和返回值。現在,這是我在使用程序集時通常不確定的事情。在程序集中傳遞子程序的參數和返回值
所以根據約定,如果我理解得很好,參數將按順序從寄存器r0 - r4開始傳遞,然後使用其他參數堆棧。返回值傳遞給r0。
現在,這是我很困惑。如果我應該保存r0的上下文並在此之後彈出它,則無法返回結果,唯一的辦法是破壞第一個參數。有什麼解決方法嗎? 在此先感謝你們!
當您返回r0的返回值時,調用者預計您將執行此操作。調用者不會期望r0仍然包含與原始第一個參數相同的值,因爲r0特別是返回值所在的位置。
正常情況下,ARM calling convention requires that the subroutine preserves r4 through r11,而不是r0到r3。所以沒有任何矛盾。
爲什麼不自己嘗試一下,看看編譯器做了什麼?
unsigned int fun (unsigned int a, unsigned int b)
{
return(a+b);
}
編譯到對象和拆卸
arm-none-eabi-gcc -O2 -c fun.c -o fun.o
arm-none-eabi-objdump -D fun.o
,其結果是
00000000 <fun>:
0: e0810000 add r0, r1, r0
4: e12fff1e bx lr
兩個輸入a和b在使用r0和r1被傳遞。 r0-r4不必保存,特別是r0因爲它的返回值無法保存。因此,所需的C代碼將兩個操作數相加,並且由於調用約定要求結果返回r0。 r0 = r0 + r1。
編譯器必須符合慣例,否則它生成的代碼將無法正常工作,因此您可以簡單地編譯代碼並反彙編以查找相當多關於特定編譯器和目標的調用約定。
所以我想調用者有責任在調用函數之前保存r0的上下文。 – as3rdaccount
從您發佈的鏈接:*「r0到r3:用於保存傳遞給子例程的參數值,並保持從子例程返回的結果」*。 – m0skit0