淺談MDK, IAR,CLANG和GCC的局部變量字節對齊處理差異(2023-10-13)

視頻:

https://www.bilibili.com/video/BV1CB4y1Z7kA


問題由來:

早期這個帖子裏面的局部變量對齊僅測試了MDK AC5,但項目中使用AC6發現了新問題,看來AAPCS規約研究的還是不夠細:

https://www.armbbs.cn/forum.php?mod=viewthread&tid=109400

當時對局部變量的描述如下:局部變量使用的是棧空間(除了靜態局部變量和編譯器優化不使用棧,直接用寄存器做變量空間),也就是大家使用在xxxx.S啓動文件開闢的stack空間。

在M內核裏面,局部變量的對齊問題如果研究起來是最燒腦的,這個涉及到AAPCS規約(Procedure Call Standard for the Arm Architecture,  Arm架構的程序調用標準)。

 

上面這個貼圖最重要,僅需理解上面這兩條就可以,意思是說,棧地址是全程至少保持4字節對齊的,因爲M內核的硬件長做了處理,SP最低兩個bit,bit0和bit1直接固定爲0了。

但是在程序調用入口處必須滿足8字節對齊,對於C語言,不需要用戶去管,編譯器都幫我們處理好了,先來個簡單的示例壓壓驚:

 

而彙編文件是需要用戶去處理的。以xxx.S啓動文件爲例,通過僞指令PRESERVE8來保證

 

那麼問題來了,我們搞個4對齊是不是會出問題,一般情況下也沒問題的,但特殊情況下不行,特別調用C庫的sprintf和printf函數,直接給你輸出個不知所以然的結果來。比如我在H7上做如下測試:

 

輸出結果:


總結:

MDK AC5和IAR的用法差不多,MDK AC6和GCC的用法差不多視頻裏面做了詳細對比測試)。

對於GCC和MDK AC6,大家可以手動添加__ALIGNED()設置對齊,這個原定義在CMSIS軟件的頭文件裏面。

#define __ALIGNED(x)                           __attribute__((aligned(x)))

 

AC6定義如下:

#define __ALIGNED(x)                           __attribute__((aligned(x)))

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章