本節課的第一個程序韋老師是想讓大家見識一下未定義異常,而第二個程序是對第一個程序進行改進,防止在某些條件下執行不了,下面就來講一下第2個程序改進了哪些地方并且有什么用。
程序在此路徑中:源碼文檔圖片\源碼\源碼_20180321_添加傳感器\014_und_exception_014_004
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 第一個程序中uart0_init所在地址為300001e4
?
假設我們為NAND啟動,在清除了BSS段之后,我們的程序完全拷貝到SDRAM里了,如果我們的程序很大,那么uart0_init就有可能在4K之后,那么采用b1相對跳轉必定會出錯,所以我們必須使用絕對地址來跳轉到SDRAM上,修改代碼如下:
使用ldr偽指令實現絕對跳轉把程序跳轉到SDRAM上去,不過其實這種做法也有可能有“危險”,下面我們結合反匯編來看一下
第58行把地址為0X300000dc的內存的值300000b0賦給了pc,也就是使程序跳轉到了sdram:處的bl 300001f0,然后再跳轉到uart0_init。ldr偽指令的執行機制是這樣的:把sdram這個地址放到內存中,內存的地址由編譯器幫我們做好,一般放在.S匯編文件的最后,然后再把這個內存的值賦給pc實現絕對跳轉,倘若我們的.S文件大過4K,那豈不是也會出錯,其實我們可以人為地來修改這個內存的地址,我們可以這樣做(下面以未定義異常來舉例說明):
當我們程序出現未定義異常時,會自動跳轉到第7行的ldr pc, und_addr,該語句把und_addr(30000008)這個地址里的值(3000000c)賦給了pc,從而實現了絕對跳轉,可以看到,我們人為地加入了und_addr:就是把存放要賦給pc的值的內存放到前面來(僅僅在_start:之后,_start:段存放的信息很少,所以不會出現上面用ldr偽指令存在的問題)
?