歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux編程 >> Linux編程

TX2440 裸跑實驗-匯編C語言混編(ADS1.2編譯) 進階(二)

一.實驗目的:
 
理解匯編的編程結構,有助於學習ARM匯編與C語言的調用關系,熟悉堆棧的調用關系.
 
二.實驗環境:
 
TX2440平台
 
三.實驗工具:
 
ADS1.2 + AXD + JLINK調試
 
四.實驗步驟:
 
1.在ads 上建立新工程,增加兩個源文件call_C_func.s 和 func.c
 
1)call_C_func.s源碼 
 
;我的assembler程序,EastonWoo procedure
 
 area init,code,readonly
  import add_8
  import main
  export assembler_add_4
  export assembler_add_5
  export assembler_add_8
 
  entry ;一個進程中至少有一個.
 
 start
  ldr sp,=0x33ff8000  ;程序有效開始指令地址:0x30000000,,堆棧設在內存裡面,也就是大於0x30000000,注意不要跟代碼區沖突;
      ;如果設成0x1000,是寫不進棧的,讀出來是0xFFFFFFFF.
 
 
  ;********************一:匯編中調用C語言函數:***************************
  stmfd sp!,{r0-r3};start看作子程序,保護好r0-r3 壓棧
 
  ;5個實參:優先使用ip,即r0-r3,其中ip.ip作為第5個實參
  ;6個實參:優先使用ip,lr,即r0-r3,ip,lr.其中ip,lr分別作為第5,6個實參.
              ;其中lr會在子程序壓棧,出棧.
  ;7個實參:優先使用ip,lr,和一個保存局部變量的寄存器v1,即r0-r3,ip,lr,v1.其中ip,lr,v1分別作為第5,6,7個實參.
              ;其中lr,v1會在子程序壓棧,出棧
  ;8個實參:優先使用ip,lr,和二個保存局部變量的寄存器v1,v2,即r0-r3,ip,lr,v1,v2.其中ip,lr,v1,v2分別作為第5,6,7,8個實參.
              ;其中lr,v1,v2會在子程序壓棧,出棧
  ;如此類推...
  ;15個參數開始就更復雜了.因為所有的局部變量寄存器全用了.4+2+8=14.以後有時間再來研究.
 
  ;8個參數例子,調用C函數例子.
  mov v2,#8   
 mov v1,#7
  mov lr,#6
  mov ip,#5
  stmfd sp!,{v1-v2} ;壓棧,先壓8,7,也就釋放了v1,v2寄存器.add_8裡會用到這些寄存器.
  stmfd sp!,{ip,lr} ;壓棧,再壓6,5,也就釋放了ip,lr寄存器.add_8裡會用到這些寄存器.
  mov r3,#4
  mov r2,#3
  mov r1,#2
  mov r0,#1
  bl add_8                ;返回值為r0
  add sp,sp,#16          ;出棧.
 
 
  ;********************二:C語言中調用匯編函數:***************************
  mov v2,#8    ;8個實參進棧.這裡就不重復敘述了.
  mov v1,#7
  mov lr,#6
  stmfd sp!,{v1-v2} ;壓棧,先壓8,7,也就釋放了v1,v2寄存器.add_8裡會用到這些寄存器.
  stmfd sp!,{ip,lr} ;壓棧,再壓6,5,也就釋放了ip,lr寄存器.add_8裡會用到這些寄存器.
  mov r3,#4
  mov r2,#3
  mov r1,#2
  mov r0,#1
  bl main                  ;bl已經保存了b over 這個地址到lr.
  add sp,sp,#16            ;出棧.
 

 ldmfd sp!,{r0-r3}
  b over
 

assembler_add_4  ;子程序直接使用r0-r3這四個實參.
  add r0,r0,r1
  add r0,r0,r2
  add r0,r0,r3
  mov pc,lr
 
 assembler_add_5  ;子程序直接使用r0-r3這四個實參和ip這個第5個實參.
  add r0,r0,r1
  add r0,r0,r2
  add r0,r0,r3
  add r0,r0,ip
  mov pc,lr
 
 ;這個8位的匯編函數相當於之前我們討論的8個參數的被調用C函數的反匯編代碼.
 assembler_add_8  ;前4個實參,子程序直接使用r0-r3這四個實參;後4個實參分別由ip,lr,v1-v2都是在棧裡得來.
  stmfd sp!,{v1-v2,lr}
  add ip,r13,#0x14
  ldmia ip,{v1-v2}
  ldr ip,[r13,#0xc]
  ldr lr,[r13,#0x10]
  add r0,r0,r1
  add r0,r0,r2
  add r0,r0,r3
  add r0,r0,ip
  add r0,r0,lr
  add r0,r0,v1
  add r0,r0,v2
  ldmfd sp!,{v1-v2,pc}
 
 over
  nop  ;無用功.為了編譯器不報警
  end

Copyright © Linux教程網 All Rights Reserved