2010-11-05 129 views
1

我正在使用匯編中的bootloader程序,我經常調用C函數來一次發送和接收字符。我使用的控制器似乎只有3個經常使用的通用寄存器。除此之外,我將一些字節存儲在固定的RAM位置。混合彙編語言和C程序

因此,我的問題是: C函數將覆蓋這些在Assembly中定義的RAM位置嗎?

我在做這些C函數前後的相關寄存器的PUSH和PULL。

回答

1

如果我正確理解你的問題,你擔心你的裝配模塊中使用的RAM位置與C模塊中聲明的某些變量重疊。您可以檢查鏈接器輸出的列表文件以確定是否是這種情況。鏈接器列表文件將顯示您的C模塊使用的所有RAM地址,您可以將它們與彙編模塊中使用的固定RAM位置進行比較。

請注意,如果您的鏈接器不會自動生成列表文件,則必須通讀鏈接器的文檔才能找到正確的命令行選項。

+1

爲了擴展這一點,您可以使用鏈接器爲RAM中的特殊區域定義指定的內存位置。這樣做也會保留區域,保護它們免受其他符號的影響。 – 2010-11-05 21:07:44

1

只要您在進行c調用時保持堆棧中的先前值,您應該沒問題。只要確保你在通話之前推入堆棧並在返回後彈出堆棧。

+1

我想補充一點,如果空間有限,請確保RAM位置儘可能遠離堆棧。 – user470379 2010-11-05 17:50:09

+1

比這更復雜。這取決於調用約定。 – 2010-11-05 20:30:49

1

這一切都取決於C代碼編譯的C調用約定。調用約定是調用者和被調用者將如何傳遞數據到函數並返回值。這包括在調用之前/之後誰會做備份寄存器到堆棧中的任何事情,在調用C函數之前是否需要準備寄存器,能否保證寄存器將返回它們原來的樣子等。

您需要了解C代碼是如何編譯的(使用Calling Convention設置)。請注意,這也是架構特定的。不同的調用約定的總結和每個什麼可嗣繼承在Wikipedia在這裏找到一個描述:

http://en.wikipedia.org/wiki/Calling_convention

http://en.wikipedia.org/wiki/X86_calling_conventions

在x86上的cdecl和STDCALL是最流行的約定。 cdecl表示你的ASM代碼應該進行清理,而stdcall表示被調用的函數負責它。如果您有C函數的源代碼,我會建議將必要的標誌傳遞給編譯器,使其成爲「Callee清理」約定(通常是stdcall,但safecall和fastcall也是選項),這意味着您可以安全地調用C功能而不用擔心註冊表損壞。

+1

我不確定這個問題是關於調用約定的。 「除了我在固定RAM位置存儲了一些字節」這句話意味着存儲在固定RAM位置中的字節與調用C代碼的彙編代碼無關嗎? – semaj 2010-11-05 20:53:05