【转】ARM汇编编程-模式切换_Detective_ALong_新浪博客

网上找了一些解释:

 

;常量定义
USR_STACK_LENGTH        EQU                64
SVC_STACK_LENGTH        EQU                0
FIQ_STACK_LENGTH        EQU                16
IRQ_STACK_LENGTH        EQU                64
ABT_STACK_LENGTH        EQU                0
UND_STACK_LENGTH        EQU                0
;代码段
                AREA        EXAMPLE5,CODE,READONLY
                ENTRY
                CODE32
START        MOV                R0,#0
                MOV                R1,#1
                MOV                R2,#2
                MOV                R3,#3
                MOV                R4,#4
                MOV                R5,#5
                MOV                R6,#6
                MOV                R7,#7
                MOV                R8,#8
                MOV                R9,#9
                MOV                R10,#10
                MOV                R11,#11
                MOV                R12,#12


                ;当前的模式是管理模式,在调用子程序INITSTACK后会自动把返回地址存入LRsvc,但是会不会把CPSR也备份到SPSR中呢,经过实际
                ;验证是不能,保存CPSR的实现是在异常模式下实现的,在进入异常后,既要保存返回地址,又要保存CPSR到相应模式下的SPSR中,
                ;但是在子程序调用中只保存返回地址,不保存CPSR到相应模式的SPSR中
                ;芯片复位之后是管理模式,所以在调用子程序之前一直是管理模式
                BL                INITSTACK
                ;打开中断
                MRS                R0,CPSR
                BIC                R0,R0,#0X80
                MSR                CPSR_cxsf,R0
                ;切换到用户模式
                MSR                CPSR_c,#0XD0
                MRS                R0,CPSR
                ;切换到管理模式,切换成功了吗?为什么?
                ;因为我们的程序进入了用户模式,用户模式不是特权模式,根本没有权利去写CPSR,所以此处读出的CPSR仍然是用户模式
                ;用户模式下是不能为所欲为的,那么用户模式下如何进入特权模式呢?SWI(软件中断)可以使我们进入特权模式,在有操作系统的,
                ;可以通过调用SWI去切换模式
                ;现在应该理解在操作系统中,我们的应用程序运行在用户模式下,而操作系统运行在系统模式下
                MSR                CPSR_c,#0XDF
                MRS                R0,CPSR
               
                B                .
    

           
INITSTACK
                MOV                R0,LR                        ;为什么要在这里保存LR到R0?直接到子程序的最后直接MOV PC,LR不更省事吗?答案是,我们的程序在特权模式下,
                ;改变了存储器的模式,使我们的存储器进入了不同的模式,我们刚进入子程序时时管理模式,我们的返回地址就存储在管理模式下的LR,或者
                ;简写成LRsvc,但是你的子程序时改变存储器模式的,就有可能不是管理模式,那么,你如何返回地址呢?因为在那个模式下的LR并不是我们需要的
                ;返回地址,只有管理模式下的LR才是我们要的返回地址,所以这里他把地址存进了R0中,因为R0在所有存储器模式下都一样的
        

       
                ;设置管理模式的堆栈
                MSR                CPSR_c,#0XD3        ;
                LDR                SP,STACKSVC                ;
                ;设置中断模式的堆栈                       
                MSR                CPSR_c,#0XD2        ;
                LDR                SP,STACKIRQ                ;
                ;设置快中断模式的堆栈
                MSR                CPSR_c,#0XD1        ;
                LDR                SP,STACKFIQ                ;
                ;设置中止模式的堆栈
                MSR                CPSR_c,#0XD7        ;
                LDR                SP,STACKABT                ;
                ;设置未定义模式的堆栈               
                MSR                CPSR_c,#0XDB        ;
                LDR                SP,STACKUND                ;
                ;设置系统模式的堆栈
                MSR                CPSR_c,#0XDF        ;
                LDR                SP,STACKUSR                ;
                ;最后我们的系统返回,但是我们的系统在什么模式呢?答案是系统模式,也就是说,刚进入子程序时,我们是管理模式,但是当退出子程序时,我们是系统模式
                MOV                PC,R0                        ;
   

            
;这个里面存放的是堆栈的指针,能看出是什么样的堆栈吗?
;没错是满递减堆栈,从"+"号看出来的,也就是指针指向堆栈空间地址的最高位置,当入栈时,地址是减少的,这个堆栈也是符合C语言的堆栈
;C语言的堆栈并不是什么堆栈都适合,是满递减的               
STACKUSR                DCD                USRSTACKSPACE+(USR_STACK_LENGTH-1)*4
STACKSVC                DCD                SVCSTACKSPACE+(SVC_STACK_LENGTH-1)*4
STACKIRQ                DCD                IRQSTACKSPACE+(IRQ_STACK_LENGTH-1)*4
STACKFIQ                DCD                FIQSTACKSPACE+(FIQ_STACK_LENGTH-1)*4
STACKABT                DCD                ABTSTACKSPACE+(ABT_STACK_LENGTH-1)*4
STACKUND                DCD                UNDSTACKSPACE+(UND_STACK_LENGTH-1)*4   

            
;下面是我们的堆栈空间,NOINIT表示没有初始化,ALIGN=2表示是4字节对齐的               
                AREA        MYSPACE,DATA,NOINIT,ALIGN=2
USRSTACKSPACE        SPACE        USR_STACK_LENGTH*4
SVCSTACKSPACE        SPACE        SVC_STACK_LENGTH*4
IRQSTACKSPACE        SPACE        IRQ_STACK_LENGTH*4
FIQSTACKSPACE        SPACE        FIQ_STACK_LENGTH*4
ABTSTACKSPACE        SPACE        ABT_STACK_LENGTH*4
UNDSTACKSPACE        SPACE        UND_STACK_LENGTH*4
                END

 

:intistack scv irq fiq abt und的sp有何关系

usr sp=svc sp

irq sp=usr sp+256

fiq sp=irq sp+64

abt sp=und sp=fiq sp

根据RW base设置的不同sp也不同,不过关系是这样的

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值