函數未聲明引發的怪異現象

By: Ailson Jack
Date: 2020.07.05
個人博客:http://www.only2fire.com/
本文在我博客的地址是:http://www.only2fire.com/archives/120.html,排版更好,便於學習,也可以去我博客逛逛,興許有你想要的內容呢。

1.問題描述

    最近進行ARM嵌入式系統開發過程中遇到一個問題,就是打印浮點數據不正確。這裏的打印函數在其他文件定義的,在main.c中調用了打印函數,但是並沒有include打印函數的頭文件,編譯能夠正確的編譯過去,但是打印浮點數據時浮點數據的內容始終不正確,比如kprintf("float_num:%f\r\n", 12.06);實際顯示的內容可能是:float_num:0.0000。

    最開始以爲浮點的堆棧處理問題,後來檢查浮點的入棧和出棧並沒有什麼問題,後來調試發現kprintf("float_num:%f\r\n", 12.06);這句代碼的彙編格式使用d0在保存浮點數據,正常來說ARM傳遞參數使用的是r0,r1,r2,r3寄存器或者堆棧,這明顯就不對,採用的貌似是編譯器的通用參數處理方式。當然了導致這個問題的原因就是kprintf這個函數並未聲明,因爲kprintf函數未聲明,編譯器在編譯當前文件時,並不知道kprintf函數的參數及順序,因此採用的貌似是編譯器的通用參數處理方式。

    kprintf函數未聲明時,kprintf("float_num:%f\r\n", 12.06);對應的彙編代碼爲:

vldr    d0, [pc, #188]

ldr     r0, [pc, #200]

bl      kprintf

    kprintf函數在main.c文件中聲明瞭時,kprintf("float_num:%f\r\n", 12.06);對應的彙編代碼爲:

add    r3, pc, #252

ldrd   r2, r3, [r3]

ldr    r0, [pc, #188]

bl     kprintf

    函數未聲明除了造成上述問題之外(參數傳入的不正確導致結果出錯),也可能導致結果正確,但是返回的結果不正確(比如一個函數返回double型的結果,如果函數未聲明就使用,可能會返回4字節的結果,導致結果返回錯誤)。

    函數未聲明時,kprintf("int_num:%d\r\n", 15);能夠正確的顯示,因爲此時15這個值能夠通過普通寄存器(r0/r1/r2/r3)傳遞,因此不會出現打印浮點數的問題。如果傳遞的參數或者返回的值,不能通過普通寄存器(r0/r1/r2/r3)傳遞時,就可能出現奇怪的問題了。

2.問題解決方法

    解決這個問題的方法自然是,在使用到kprintf的文件中include打印函數kprintf的頭文件。

3.小結

    對於開發過程中,如果編譯時提示"warning: implicit declaration of function 'xxx'"這類的信息,一定還是加上這些函數的聲明。如果不添加函數聲明,編譯雖然能夠通過,但是遇到我上面提及的怪異問題,調試可能都不知如何下手,謹記吧。

如果這篇文章對你有幫助,記得點贊和關注博主就行了^_^。
排版更好的內容見我博客的地址:http://www.only2fire.com/archives/120.html
注:轉載請註明出處,謝謝!^_^

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