我試圖在Cortex-M3處理器(ARMv7-M架構)上構建調用堆棧,沒有OS(裸機)。但是,這個ABI沒有幀指針寄存器。因此,當我沒有幀指針時,我正在努力生成調用堆棧。ARM:無幀指針的調用堆棧生成
無論使用-mapcs-frame
,-fno-omit-frame-pointer
和-O0
選項與GCC,都不保留幀指針。我想知道是否有不同的ABI我可以強制GCC使用,所以我有一個幀指針/堆棧幀?如果沒有,是否還有其他可靠的方法來生成調用堆棧?
在此先感謝。
我試圖在Cortex-M3處理器(ARMv7-M架構)上構建調用堆棧,沒有OS(裸機)。但是,這個ABI沒有幀指針寄存器。因此,當我沒有幀指針時,我正在努力生成調用堆棧。ARM:無幀指針的調用堆棧生成
無論使用-mapcs-frame
,-fno-omit-frame-pointer
和-O0
選項與GCC,都不保留幀指針。我想知道是否有不同的ABI我可以強制GCC使用,所以我有一個幀指針/堆棧幀?如果沒有,是否還有其他可靠的方法來生成調用堆棧?
在此先感謝。
關於上述註釋,ARM調用標準與Thumb相同,請參閱(AAPCS Arm calling standard)指令集不同,但CPU寄存器設置不同。
我寧願在評論中提問,但至今我沒有足夠的分數。 考慮到這一點....
你有一個二進制成功構建和執行,但你試圖轉儲某種調用跟蹤?我的困惑是'無幀指針寄存器'語句 - r13是堆棧幀指針。我認爲你指的是存儲幀指針。
它已經有一段時間,但我認爲這些是我用
臂-NONE-EABI-GCC選項 - -nostdlib -ggdb -mthumb -mcpu =皮質-M3 -mtpcs幀 - mtpcs葉幀myfile.c文件
這是在gcc-arm-none downloaded from linaro. GDB能夠做的回溯與愛特梅爾SAM3X這些選項。 Thumb ABI與ARM EABI相同,或者至少似乎是通過objdump -D查看彙編程序。
前一幀指針被存儲在r7中當指定-fno-省略幀指針(或暗示)
void test2(int i) {}
void main() { test(0);
編譯時-fomit幀指針
00008000 <test2>:
8000: b082 sub sp, #8
8002: 9001 str r0, [sp, #4]
8004: b002 add sp, #8
8006: 4770 bx lr
00008008 <main>:
8008: b508 push {r3, lr}
800a: f04f 0000 mov.w r0, #0
800e: f7ff fff7 bl 8000 <test2>
8012: bd08 pop {r3, pc}
編譯與-fno-omit-幀指針
00008000 <test2>:
8000: b480 push {r7}
8002: b083 sub sp, #12
8004: af00 add r7, sp, #0
8006: 6078 str r0, [r7, #4]
8008: f107 070c add.w r7, r7, #12
800c: 46bd mov sp, r7
800e: bc80 pop {r7}
8010: 4770 bx lr
8012: bf00 nop
00008014 <main>:
8014: b580 push {r7, lr}
8016: af00 add r7, sp, #0
8018: f04f 0000 mov.w r0, #0
801c: f7ff fff0 bl 8000 <test2>
8020: bd80 pop {r7, pc}
8022: bf00 nop
所以使用r7來到前一個堆棧幀,然後得到來自該位置的下一個r7等等。
如何告訴GCC使用EABI?另外,堆棧指針是否指向不適合寄存器的局部變量的開始? – Saul
正確,sp將指向進入'功能'的第5個參數,例如foo(1,2,3,4,5)調用者將在sp位置存儲'5',r0..r4將包含1,2,3,4被調用者將從sp位置讀取'5'。請注意,堆棧是'在寫入之前減少' – SilverCode
我無法使用GDB,因爲我沒有操作系統,並且在MBED板上運行的映像不是ELF,只是二進制機器代碼。您說我正在嘗試生成呼叫跟蹤是正確的。沒有幀指針,這是不可能的,因爲我不能走棧。因此我的問題是我如何強制GCC使用幀指針(因爲'-fno-omit-frame-pointer'似乎沒有任何效果),或者說,我怎樣才能找到調用函數的地址,並在此之前調用函數的地址,無限。 – Saul
爲什麼你需要一個調用堆棧的幀指針寄存器?我很困惑。幀指針寄存器是一個懶惰的解決方案,只需使用堆棧指針而不浪費其他寄存器。只需編譯一些C代碼,看看編譯器是如何模仿它的。 –
其實拇指與armv7m拇指2擴展(約140-150附加說明),這意味着你可以使用手臂式解決方案。 –
我不能只使用堆棧指針,因爲我不知道調用函數中每個堆棧幀的大小。同樣在浪費寄存器方面,GCC的ARM彙編輸出非常奇怪,因爲它使用一個寄存器作爲堆棧指針的近似副本(儘管我正在使用'-OO'編譯) – Saul