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

相关推荐