2013-03-12 77 views
1

我正在爲Raspberry Pi編寫一些裸機代碼,並且在Windows上收到來自ARM交叉彙編程序的意外警告。導致警告的指示是:GNU ARM彙編程序出現意外警告

stmdb sp!,{r0-r14}^ 

ldmia sp!,{r0-r14}^ 

的警告是:

警告:基址寄存器寫回是不可預知的

我可排序的理解這一點,儘管'^'修飾符告訴處理器存儲th e用戶模式寄存器的副本,它不知道當指令執行時處理器將處於什麼模式,並且似乎沒有辦法告訴它。我有點更關注以獲取同樣的警告:

stmdb sp!,{r0-r9,sl,fp,ip,lr}^ 

和:

ldmia sp!,{r0-r9,sl,fp,ip,lr}^ 

儘管我沒有明確存儲任何 SP寄存器。

我的問題是,雖然我大約15年前曾經做過很多彙編代碼,但ARM代碼對我來說是新的,我可能會誤解某些東西!另外,如果我可以安全地忽略這些警告,是否有辦法壓制它們?

回答

1

術語 「回寫」 指在寄存器列表中的存在或不存在的SP,但到!符號,這意味着該指令應該更新SP值與傳輸區域地址的結束。基址寄存器(SP)值將在當前模式下使用,而不是在用戶模式下使用,因此您仍然可以將用戶模式SP值加載或存儲到堆棧中。從ARM ARM B9.3.6 LDM(用戶登記):

在比系統模式下,加載多個(用戶登記)使用的地址從一連續的內存位置 負載的多個用戶模式寄存器以外的PL1模式基址寄存器。加載的寄存器不能包括PC在內的 。處理器通常使用當前模式讀取基址寄存器值 ,以確定寄存器 的正確Banked版本。該指令不能回寫到基址寄存器。

編碼圖通過將位21(W,寫回)指定爲'(0)'來反映這一點,這意味着如果該位不爲0,則結果是不可預測的。

因此,解決方案只是不指定!,並在必要時手動遞減或增加SP。

+0

啊,我錯過了架構參考手冊中的那一點,但我必須承認,我一直在使用ARM1176JZF-S技術參考手冊來獲取大部分信息,但似乎並沒有詳細討論這個問題!我發現使用Google的警告(不是很多!)的所有解釋都表示,警告是由於您正在對正在加載/存儲的寄存器進行回寫造成的。我知道回寫是指更新基址寄存器。 – williamssimonp 2013-03-13 09:04:21

3

ARM體系結構參考手冊指出在用戶寄存器的LDM/SMT中不允許寫回。在異常返回情況下允許使用,其中pc位於註冊列表中。

LDM(異常返回)

LDM{<amode>}<c> <Rn>{!},<registers_with_pc>^ 

LDM(用戶登記)

LDM{<amode>}<c> <Rn>,<registers_without_pc>^ 
+0

因此,要使用第一種形式從異常中返回,您必須執行沒有寫回的寄存器存儲操作,更新堆棧指針,然後可以使用具有寫回的版本返回!限制似乎有點奇怪,但我確信這是有原因的。至少它允許回寫,如果PC正在加載,否則它將是無用的! – williamssimonp 2013-03-13 15:59:44