热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

[嵌入式]Cortex-A8处理器编程(下)

第3章Cortex-A8处理器编程3.6指令系统ARM伪指令不属于ARM指令集中的指令,是为了编程方便而定义的。伪指令可以像其它ARM指令一样使用,但在编译时这些指令将被等效的ARM指令代替。A

第3章 Cortex-A8处理器编程

3.6  指令系统

ARM伪指令不属于ARM指令集中的指令,是为了编程方便而定义的。伪指令可以像其它ARM指令一样使用,但在编译时这些指令将被等效的ARM指令代替。ARM伪指令有四条,分别为ADR伪指令、ADRL伪指令、LDR伪指令、NOP伪指令。

ARM伪指令——小范围的地址读取

ADR伪指令将基于PC相对偏移的地址值或基于寄存器相对偏移的地址值读取到寄存器中。在汇编编译器编译源程序时,ADR伪指令被编译器替换成一条合适的指令。通常,编译器用一条ADD指令或SUB指令来实现该ADR伪指令的功能,若不能用一条指令实现,则产生错误,编译失败。

 

地址表达式expr的取指范围:

当地址值不是字对齐时,其取值范围为-255~255;

当地址值是字对齐时,其取值范围为-1020~1020;

当地址值是16字节对齐时,其取值范围将更大。

应用示例(源程序):

  ...

    ADR     R0,Delay    

    ...

Delay

    MOV     R0,r14

    ...

使用伪指令将程序标号Delay的地址存入R0

ARM伪指令——中等范围的地址读取

ADRL伪指令将基于PC相对偏移的地址值或基于寄存器相对偏移的地址值读取到寄存器中,比ADR伪指令可以读取更大范围的地址 。在汇编编译器编译源程序时,ADRL伪指令被编译器替换成两条合适的指令。若不能用两条指令实现,则产生错误,编译失败。

 

地址表达式expr的取指范围:

当地址值不是字对齐时,其取址范围为-64K~64K;

当地址值是字对齐时,其取址范围为-256K~256K;

当地址值是16字节对齐时,其取址范围将更大。

应用示例(源程序):

...

    ADRL    R0,Delay    

    ...

Delay

    MOV     R0,r14

    ...

使用伪指令将程序标号Delay的地址存入R0

ARM伪指令——大范围的地址读取

LDR伪指令用于加载32位的立即数或一个地址值到指定寄存器。在汇编编译源程序时,LDR伪指令被编译器替换成一条合适的指令。若加载的常数未超出MOV或MVN的范围,则使用MOV或MVN指令代替该LDR伪指令,否则汇编器将常量放入文字池,并使用一条程序相对偏移的LDR指令从文字池读出常量。

 

应用示例(源程序):

   ...

    LDR     R1,=InitStack

    ...

InitStack    

    MOV     R0, LR

    ...

使用伪指令将程序标号InitStack的地址存入R1

注意:

1.从指令位置到文字池的偏移量必须小于4KB;

2.与ARM指令的LDR相比,伪指令的LDR的参数有“=”号。

ARM伪指令——空操作伪指令

NOP伪指令在汇编时将会被代替成ARM中的空操作,比如可能是“MOV  R0,R0”指令等。NOP可用于延时操作。

 

应用示例(延时子程序):

    Delay

    NOP;空操作

    NOP

    NOP

    SUBS    R1,R1,#1  ;循环次数减一

    BNE     Delay      ;如果循环没有结束,跳转Delay继续

    MOV     PC,LR       ;子程序返回

3.7 ARM汇编程序规范

     在只关心系统所具有功能的设计中,采用高级编程语言编写程序更合适,由于其隐藏了CPU执行指令的许多细节。但是,CPU执行指令的细节差异会反应在系统的非功能特性上,例如系统程序的规模和运行速度。因此,掌握汇编语言程序设计对于嵌入式系统的设计者来说是非常必要的。

ARM汇编程序中每一行的通用格式为:

{标号} {指令|指示符|伪指令} {;注解}

     在ARM汇编语言源程序中,除了标号和注释外,指令、伪指令和指示符都必须有前导空格,而不能顶格书写。如果每一行的代码太长,可以使用字符“\”将其分行书写,并允许有空行。指令助记符、指示符和寄存器名既可以用大写字母,也可以用小写字母,但不能混用。注释从“;”开始,到该行结束为止。

 

标号

标号代表一个地址,段内标号的地址值在汇编时确定,段外标号的地址值在链接时确定。在此要区别程序相对寻址和寄存器相对寻址。在程序段中,标号代表其所在位置与段首地址的偏移量,根据程序计数器PC和偏移量计算地址称为程序相对寻址。在映像中定义的标号代表标号到映像首地址的偏移量,映像的首地址通常被赋予一个寄存器,根据该寄存器值与偏移量计算地址称为寄存器相对寻址。

指示符

 

 

 

 

 

预定义变量

ARM汇编器对ARM的寄存器进行了预定义,所有的寄存器和协处理器名都是大小写敏感的。预定义的寄存器如下:

·R0~R15或r0~r15;

·a1~a4(参数、结果或临时寄存器,与r0~r3同义);

·v1~v8(变量寄存器,与r4~r11同义);

·sb和SB(静态基址寄存器,与r9同义);

·sl和SL(堆栈限制寄存器,与r10同义);

·fp和FP(帧指针,与r11同义);

·ip和IP(过程调用中间临时寄存器,与r12同义);

·sp和SP(堆栈指针,与r13同义);

·lr和LR(链接寄存器,与r14同义);

·pc和PC(程序计数器,与r15同义);

·cpsr和CPSR(程序状态寄存器);

·spsr和SPSR(程序状态寄存器);

·f0~f7和F0~F7(FPA寄存器);

·s0~s31和S0~S31(VFP单精度寄存器);

·d0~d15和D0~D15(VFP双精度寄存器);

·p0~p15(协处理器0~15);

·c0~c15(协处理器寄存器0~15)。

内置变量

ARM汇编器所定义的内置变量如表所示。值得注意的是内置变量的设置不能用SETA、SETL或SETS等指示符来设置,只能用表达式或条件来设置。例如:

IF  {ARCHITECTURE} = “4T”

 

 

子程序调用规则

ARM9处理器的子程序调用指令有别于Intel X86的子程序调用指令CALL,此小节再对这一特点进行归纳。另外,本小节还将介绍C或C++语言编写的程序与汇编语言编写的程序之间相互调用的规则。

汇编子程序调用

程序设计时,通常会把完成某个特定功能的一段程序代码编写成子程序,在需要的地方进行调用。ARM汇编程序中,使用下面语句调用子程序。

    BL  next

    其中,next为子程序中的第一条指令代码的标号。

    任何一个子程序进入前,处理器需要保存主程序中的现场,即需要保存当前工作寄存器(注意:当采用了子程序嵌套调用时,应该保存LR寄存器)。汇编指令BL的功能是将BL指令的下一条指令地址放到LR寄存器中,作为返回地址。并将子程序的第一条指令地址赋予PC寄存器,实现程序转移,即进入子程序执行。子程序执行完后,通过把LR寄存器值赋予PC寄存器,实现返回。

C、C++语言程序中内嵌汇编

C、C++语言编写的程序要比汇编语言编写的程序易读性、移植性好,因此,在嵌入式系统开发时,编写系统程序大多还是采用C、C++语言。但是在某些场合有时需要采用汇编指令编写程序,以实现一些高级语言没有的功能,并提高执行效率。ARM汇编工具支持在C、C++语言程序中嵌入汇编编写的程序段,其语法格式如下:

    __asm{“指令[;指令]”}

 

汇编程序序实例--系统引导程序

掌握汇编语言程序设计对于嵌入式系统的设计者来说是非常必要的。大多数嵌入式系统加电后运行的第一段程序(在此称为系统引导程序,有时也称启动代码),往往是采用汇编语言编写的。

    系统引导程序是依赖于具体硬件环境的,除了依赖于CPU的体系结构外,还依赖于具体的板级硬件配置。

·关看门狗定时器,关中断。

·有时需要设置系统CPU的速度和时钟频率。

·设置好堆栈。系统堆栈初始化取决于用户使用哪些异常,以及系统需要处理哪些错误类型。

  一般情况下,管理模式堆栈必须设置;若使用了IRQ中断,则IRQ中断堆栈必须设置。

·如果系统应用程序是运行在用户模式下,可在系统引导程序中将系统改为用户模式并初始

  化用户堆栈指针。

·若系统使用了DRAM或其他外设,需要设置相关寄存器,以确定其刷新频率、总线宽度

  等信息。

·初始化所需的存储器空间。将系统需要读写的数据和变量从ROM拷贝到RAM里;要求快

  速响应的程序,如中断程序,也需要在RAM中运行;对Flash的擦除和写入操作也一定

  要在RAM里运行。

·跳转到C程序的入口点。

系统上电或复位后,首先执行的是“b reset”指令,系统跳转到标号为reset处接着执行,在完成了关中断、使能管理模式、初始化各模式的堆栈等功能后,执行指令“b main”跳转到C语言的主函数处执行。

 


推荐阅读
author-avatar
行侠客人生_983
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有