<dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><small id="yhprb"></small><dfn id="yhprb"></dfn><small id="yhprb"><delect id="yhprb"></delect></small><small id="yhprb"></small><small id="yhprb"></small> <delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"></dfn><dfn id="yhprb"></dfn><s id="yhprb"><noframes id="yhprb"><small id="yhprb"><dfn id="yhprb"></dfn></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><small id="yhprb"></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn> <small id="yhprb"></small><delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn>

新聞中心

EEPW首頁(yè) > 嵌入式系統 > 設計應用 > DSP編程技巧---理解函數的調用過(guò)程

DSP編程技巧---理解函數的調用過(guò)程

作者: 時(shí)間:2016-12-21 來(lái)源:網(wǎng)絡(luò ) 收藏
  在我們使用C/C++DSP進(jìn)行編程的時(shí)候,函數無(wú)疑是功能模塊劃分的重要組成部分,這些函數之間則通過(guò)顯式地調用或者中斷等方式來(lái)共同工作。除了對特定的RTS庫中的函數(例如某些數學(xué)函數)的調用按照它們內置規則進(jìn)行分配外,我們自定義的函數之間的調用則需要遵循一定的規則,了解這一過(guò)程對理解程序的執行和調試也是十分有幫助的,下面我們就來(lái)解讀一下函數的調用過(guò)程,并且可以從其中了解到CPU寄存器、FPU寄存器以及棧(stack)在這一過(guò)程中的作用。

  一.父函數調用子函數

本文引用地址:http://dyxdggzs.com/article/201612/332389.htm

  在父函數調用子函數(被調函數)時(shí),通常會(huì )執行以下的步驟:

  1.如果寄存器不是SOE類(lèi)型的(入口保存,save on entry),即它的值沒(méi)有被被調用函數占用,但是在被調用函數返回值之后又會(huì )用到該寄存器的值的話(huà),則該寄存器的值被保存在棧中。

  2.如果被調函數返回一個(gè)結構體,則調用函數會(huì )為結構體分配空間,并且把這段空間的地址作為第一個(gè)參數傳遞給被調函數,被調函數需要創(chuàng )建一個(gè)該結構體的本地副本。

  3.傳遞給被調函數的參數一般情況下會(huì )保存在寄存器中,在必要的情況下則會(huì )保存在棧中,因為寄存器的數量有限;具體的規則是:

  (1)如果目標器件是FPU,并且傳遞的有32位的浮點(diǎn)從那時(shí),則前4個(gè)浮點(diǎn)參數被保存在R0H-R3H這4個(gè)FPU寄存器中(注意與CPU寄存器AR0H-AR3H相區別)。

  (2)如果有64位的整形(longlong)參數,則第一個(gè)64位整形參數的高32位存入ACC寄存器中,低32位存入P寄存器中,其它的64位整形參數按照逆序(函數聲明中參數列表里最左邊的參數最后被壓入棧中)保存在棧中。

  此外,如果P寄存器被用于參數傳遞,則對該函數的裝入(prolog)和排空(epilog)的提取的優(yōu)化功能(通過(guò)減小性能達到減小程序尺寸)被禁止。

  (3)如果參數中有任何的32位長(cháng)整形或者浮點(diǎn)型,則第一個(gè)會(huì )放入ACC寄存器中,其它的32位參數則按照逆序保存在棧中。

  (4)指針參數被放入CPU寄存器XAR4和XAR5中,其它的指針則存入棧中。

  (5)剩余的16位的參數在CPU寄存器AL,AH,XAR4和XAR5可用的情況下,按照這一寄存器的順序被保存在它們中。

  4.任何沒(méi)有被存入寄存器的參數都會(huì )被以逆序壓入棧中,所有的32位參數在壓入棧中時(shí)都會(huì )對齊到偶數地址。

  如果一個(gè)函數的參數中使用了省略號,即參數個(gè)數是可變的,則最后一個(gè)顯式聲明的參數在壓入棧中之后,它在棧中的地址可以用來(lái)定位未顯式聲明的參數。

  5.棧指針SP必須在父函數調用子函數之前偶對齊。如果不是偶對齊,則需要把SP加1.

  6.父函數使用LCR指令(使用返回程序指針寄存器RPC的方式來(lái)進(jìn)行22位的長(cháng)調用)來(lái)調用子函數,在調用時(shí)RPC寄存器的值會(huì )被壓入棧中,從而可以把返回地址保存在RPC寄存器中。

  7.最后,棧被對齊到函數的邊界上。

  二.子函數響應父函數

  在子函數被調用時(shí),通常會(huì )執行以下的步驟:

  1.如果被調函數修改了XAR1、XAR2或者XAR3的值,則必須保存它們的值,因為在調用前后,父函數假設這3個(gè)寄存器的值在被返回之前是被保留的。如果目標是FPU,并且在被調函數中修改了R4H-R8H的值,則同樣需要保存它們的值。

  2.被調用的函數需要在棧中為所有的本地變量、臨時(shí)存儲區域已經(jīng)任何被調用的參數分配足夠的空間。在通過(guò)為SP寄存器加偏移量跳轉到被調函數之后,這段存儲空間就立刻被分配了。

  3.棧被對齊到函數的邊界上。

  4.如果被調用的函數參數中有結構體,則它實(shí)際接收到的是該結構體的指針。如果在被調函數中對該結構體進(jìn)行了寫(xiě)操作,則必須在棧中分配空間以創(chuàng )建該結構體的副本,在完成操作之后把本地結構體通過(guò)指針復制回原有的結構體。如果在被調函數中不對傳入的結構體參數進(jìn)行寫(xiě)操作,則可以通過(guò)對其指針的操作來(lái)完成參數的引用。

  5.完成參數傳入之后,被調函數執行它本身的代碼。

  6.功能執行完成之后,被調函數返回值,根據返回值的類(lèi)型,它們值的保存位置分別為:

  16位整數:AL寄存器

  32位整數:ACC寄存器

  64位整數:ACC和P寄存器

  16位或者22位指針:XAR4寄存器

  FPU下的32位浮點(diǎn)數:R0H寄存器

  結構體:其指針保存在XAR4寄存器中

  在返回結構體的情況下,例如s=f(x),其中s為結構體,f為函數,則可以直接用f(&s,x)的方式在父函數中調用子函數f,通過(guò)結構體指針,被調函數可以自動(dòng)返回結構體的值了。

  7.通過(guò)把SP中減去調用子函數時(shí)加的偏移量,SP寄存器可以重新指向父函數。

  8.被調函數恢復所有在第一步中保存的建城七隊值。

  9.被調函數使用LRETR(使用PC指針?lè )祷?指令返回,PC寄存器的值被置為RPC寄存器中的值,即返回地址,然后RPC寄存器中的原有值被推出棧并重新保存在RPC寄存器中。

  通過(guò)以上的描述,可以看出棧在函數調用前后起著(zhù)非常關(guān)鍵的中繼作用。所以,如果在調用時(shí)傳遞的參數非常多,例如傳遞了一個(gè)很長(cháng)的數組,或者有多個(gè)64位的參數,則棧很有可能沒(méi)有足夠的空間來(lái)完成參數的暫存,造成棧的溢出,甚至造成程序運行結果的異?;蛘咤e誤的輸出結果,因為編譯器無(wú)法檢查棧的溢出錯誤(除非我們自己編寫(xiě)某些代碼來(lái)檢測),所以要為棧分配一個(gè)相對較大的存儲空間,它的默認值是1K字。即使是非常小的程序,常用例程里棧的長(cháng)度也往往能達到0x400這樣的長(cháng)度。



關(guān)鍵詞: DSP編程技

評論


技術(shù)專(zhuān)區

關(guān)閉
国产精品自在自线亚洲|国产精品无圣光一区二区|国产日产欧洲无码视频|久久久一本精品99久久K精品66|欧美人与动牲交片免费播放
<dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><small id="yhprb"></small><dfn id="yhprb"></dfn><small id="yhprb"><delect id="yhprb"></delect></small><small id="yhprb"></small><small id="yhprb"></small> <delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"></dfn><dfn id="yhprb"></dfn><s id="yhprb"><noframes id="yhprb"><small id="yhprb"><dfn id="yhprb"></dfn></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><small id="yhprb"></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn> <small id="yhprb"></small><delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn>