山东大学嵌入式实验:ARM汇编与C混合编程实验—-ARM启动过程控制实验

实验目的

(1)掌握建立基本完整的ARM 工程,包含启动代码,C语言程序等;

(2)了解ARM 启动过程,学会编写简单的C 语言程序和汇编程序启动代码并进行调试;

(3)掌握如何指定代码入口地址与入口点;

(4)掌握通过memory/register/watch/variable 窗口分析判断错误。

实验环境

硬件:PC 机

软件:ADS1.2 集成开发环境

实验内容

使用汇编语言编写初始化程序,并引导至C语言main函数,用汇编语言编写延时函数实现毫秒级的延时,在C语言中调用延时函数,实现1s钟定时。

实验要求

(1)按照2.3节介绍的方法,在ADS下创建一个工程armasmc,编写3个文件,通过AXD运用单步执行方式进行调试程序,观察程序执行过程中的寄存器及存储器的变化情况。

(2)实验过程中请记录并思考以下内容:

1)如何建立异常矢量入口表?

2)如何在汇编语言中切换至C语言的main函数?

3)如何在C语言中调用汇编语言函数,并完成参数传递?

4)汇编语言函数中用到的寄存器如何保护与恢复,为什么要保护参考程序中的R11?

5)将delay.s中的R11改成R4,并将两条R11的保护与恢复语句stmfd sp!,{r11}和 ldmfd sp!{r11}删掉,在C语言程序中的语句i—-处设置端点,观察运行过程中变量i的变化情况,并解释其中的原因。

实验代码:

Init.s完成异常矢量表的建立,模式堆栈初始化,并将程序引导至C语言的main函数

;***************************************************************
; NAME: entry.s  
; Author: lihua  
; History: 2014-4-10
;***************************************************************

 IMPORT Main  ;在汇编程序调用该c程序前要在汇编语言程序中使用IMPORT伪操作来声明该c程序

  area Init,code,readonly    
  entry
  code32
; *********** Setup interrupt/exception vectors *************************
start              b Reset_Handler        ;异常矢量表,根据异常矢量表进入不同模式的中断程序      
Undefined_Handler  b Undefined_Handler
SWI_Handler        b SWI_Handler
Prefetch_handler   b Prefetch_handler
Abort_Handler      b Abort_Handler
                   nop   ;Reserved vector
IRQ_Handler        b IRQ_Handler
FIQ_Handler        b FIQ_Handler

Reset_Handler     ;Reset中断,为整个中断的实际入口点        
             bl initstack    ;初始化各模式下的堆栈指针
                             
             ;切换至用户模式堆    
             msr cpsr_c,#0xd0    ;110  10000
                 
             bl Main

halt         b halt

initstack    mov r0,lr        ;r0<--lr,因为各种模式下r0是相同的而各个模式?                            
                                   
             ;设置管理模式堆栈
             msr cpsr_c,#0xd3    ;110  10011  
             ldr sp,stacksvc
               
             ;设置中断模式堆栈
             msr cpsr_c,#0xd2    ;110  10010
             ldr sp,stackirq  
             
             ;设置快速中断模式堆栈
             msr cpsr_c,#0xd1    ;110  10001
             ldr sp,stackfiq
                                
             ;设置中止模式堆栈      
             msr cpsr_c,#0xd7    ;110  10111
             ldr sp,stackabt
                                    
            ;设置未定义模式堆栈   
             msr cpsr_c,#0xdb    ;110  11011
             ldr sp,stackund
   
             ;设置系统模式堆栈    
             msr cpsr_c,#0xdf    ;110  11111
             ldr sp,stackusr
             
             mov pc,r0 ;返回
         
  LTORG      

stackusr     dcd  usrstackspace+128
stacksvc     dcd  svcstackspace+128
stackirq     dcd  irqstackspace+128
stackfiq     dcd  fiqstackspace+128
stackabt     dcd  abtstackspace+128
stackund     dcd  undstackspace+128

  area Interrupt,data,READWRITE  ;分配堆栈空间
usrstackspace space 128
svcstackspace space 128
irqstackspace space 128
fiqstackspace space 128
abtstackspace space 128
undstackspace space 128
     
       end

C语言程序,调用汇编语言文件delay.s

/*******************************************************************
* File: armasmc.c
* Author: lihua 2014.4.10
* History:
********************************************************************/
#include <stdio.h>
int Main()
{  

  extern void delayxms(int xms);  //在C程序调用汇编程序之前需要在C语言程序中使用extern关键词来声明该汇编程序
  
  int i=100;
  
  while(1)
  {
     delayxms(1000);
     i--;
     if(i==0)
       i=100;
  }
  
  return 0;
}

汇编delay.s延时程序

;***************************************************************
; NAME: delay.s  
; Author: lihua  
; History: 2014-4-10
;***************************************************************

  EXPORT delayxms

  area delay,code,readonly    
  code32
  
;下面是延时若干ms的子程序      
delayxms
     stmfd sp!,{r11};
     sub r0,r0,#1 ;r0=r0-1
     ldr r11,=1000
loop2
     sub r11,r11,#1
     cmp r11,#0x0
     bne loop2
     cmp r0,#0x0    ;将r0与0比较
     bne delayxms   ;比较的结果不为0,则继续调用delayxms
     ldmfd sp!,{r11};
     mov pc,lr;返回
     
     end

实验结果:

1)如何建立异常矢量入口表?

答:要设置中断类型号,设置中断服务子程序段地址

2)如何在汇编语言中切换至C语言的main函数?

答:为了保证程序调用时参数的正确传递,汇编程序设计要遵守ATPCS。在C程序中不需要任何关键字来声明将被汇编语言调用的C程序,但需要在汇编语言程序之前使用IMPORT伪操作来声明该C程序。在汇编程序中通过BL指令来调用子程序。

3)如何在C语言中调用汇编语言函数,并完成参数传递?

答:为了保证程序调用时参数的正确传递,汇编程序设计要遵守ATPCS。在汇编程序中需要使用EXPORT伪操作来声明,同时,在C程序中调用该汇编程序之前需要在C语言程序中使用extern关键词来声明该汇编程序。

4)汇编语言函数中用到的寄存器如何保护与恢复,为什么要保护参考程序中的R11?

答:汇编语言函数中用到的寄存器通过压栈来保护,出栈来恢复。根据ATPCS规则,R11对应ARM 状态局部变量寄存器8,因为R11中可能含有其他重要的数据,所以要保护R11。

5)将delay.s中的R11改成R4,并将两条R11的保护与恢复语句stmfd sp!,{r11}和 ldmfd sp!{r11}删掉,在C语言程序中的语句i—-处设置端点,观察运行过程中变量i的变化情况,并解释其中的原因。

修改后的程序如图:

R4对应局部变量寄存器1,即i,所以在delay.s中,R4的值减为0,若不进行保护,则返回C程序后经i–,i值变为-1,永远不为0,无法执行if语句,导致i值一直递减下去。

© 版权声明
THE END
喜欢就支持以下吧
点赞1赞赏 分享
评论 共21条

请登录后发表评论

    暂无评论内容