第四章 基于ARM的嵌入式程序设计

上传人:laiq****ong 文档编号:243138347 上传时间:2024-09-16 格式:PPT 页数:53 大小:2.68MB
返回 下载 相关 举报
第四章 基于ARM的嵌入式程序设计_第1页
第1页 / 共53页
第四章 基于ARM的嵌入式程序设计_第2页
第2页 / 共53页
第四章 基于ARM的嵌入式程序设计_第3页
第3页 / 共53页
点击查看更多>>
资源描述
单击此处编辑母版标题样式,单击此处编辑母版文本样式,第二级,第三级,第四级,第五级,*,*,4.1.1,两种常见的,ARM,编译开发环境,ADS/SDT IDE,开发环境:它由,ARM,公司开发,使用了,CodeWarrior,公司的编译器;,集成了,GNU,开发工具的,IDE,开发环境:它由,GNU,的汇编器,as,、交叉编译器,gcc,、和链接器,ld,等组成。,4.1.2ADS,编译环境下的伪操作和宏指令,ADS,编译环境下的伪操作可分为以下几类:,符号定义(,Symbol Definition,)伪操作,数据定义(,Data Definition,)伪操作,汇编控制(,Assembly Control,)伪操作,信息报告(,Reporting,)伪操作,其他(,Miscellaneous,)伪操作,符号定义伪操作,伪操作,语法格式,作 用,GBLA,GBLA Variable,声明一个全局的算术变量,并将其初始化成,0,。,GBLL,GBLL Variable,声明一个全局的逻辑变量,并将其初始化成,FALSE,。,GBLS,GBLS Variable,声明一个全局的字符串变量,并将其初始化成空串“”。,LCLA,LCLA Variable,声明一个局部的算术变量,并将其初始化成,0,。,LCLL,LCLL Variable,声明一个局部的逻辑变量,并将其初始化成,FALSE,。,LCLS,LCLS Variable,声明一个局部的串变量,并将其初始化成空串“”。,SETA,SETA Variable expr,给一个全局或局部算术变量赋值。,SETL,SETL Variable expr,给一个全局或局部逻辑变量赋值。,SETS,SETS Variable expr,给一个全局或局部字符串变量赋值。,RLIST,name LIST,list of registers,为一个通用寄存器列表定义名称。,CN,name CN expr,为一个协处理器的寄存器定义名称。,CP,name CP expr,为一个协处理器定义名称。,DN/SN,name DN/SN expr,DN/SN,为一个双精度,/,单精度的,VFP,寄存器定义名称。,FN,name FN expr,为一个,FPA,浮点寄存器定义名称。,数据定义伪操作,伪操作,语法格式,作 用,LTORG,LTORG,声明一个数据缓冲池(也称为文字池)的开始。,MAP,MAP expr,,,base-register,定义一个结构化的内存表(,Storage Map,)的首地址。,FIELD,label,FIELD expr,定义一个结构化内存表中的数据域。,SPACE,label,SPACE expr,分配一块连续内存单元,并用,0,初始化。,DCB,label DCB expr,,,expr,分配一段字节内存单元,并用,expr,初始化。,DCD/ DCDU,label DCD expr ,,,expr,分配一段字内存单元。,DCDO,label,DCDO expr,,,expr,分配一段字对齐的字内存单元。,DCFD/ DCFDU,label DCFD,U,fpliteral,,,fpliteral,为双精度的浮点数分配字对齐的内存单元。,DCFS/ DCFSU,label DCFS,U,fpliteral,,,fpliteral,为单精度的浮点数分配字对齐的内存单元。,DCI,label DCI expr,,,expr,在,ARM,代码中分配一段字对齐的内存单元,;,在,Thumb,代码中,分配一段半字对齐的半字内存单元。,DCQ/ DCQU,label DCQ,U,literal,,,literal,分配一段以双字(,8,个字节)为单位的内存,DCW/ DCWU,label DCW,U,expr,,,expr,DCW,用于分配一段半字对齐的半字内存单元。,汇编控制伪操作,伪操作,语法格式,作 用,IF,,,ELSE,及,ENDIF,IF logical expression,ELSE,ENDIF,能够根据条件把一段源代码包括在汇编语言程序内或者将其排除在程序之外。,WHILE,及,WEND,WHILE logical expression,WEND,能够根据条件重复汇编相同的一段源代码。,MACRO,、,MEND,及,MEXIT,MACRO,$label macroname,$parameter,,,$parameter,;宏代码,MEND,MACRO,标识宏定义的开始,,MEND,标识宏定义的结束。,MERIT,用于从宏中跳转出去。用,MACRO,和,MEND,定义的一段代码,称为宏定义体。通过宏名称来调用宏。,信息报告伪操作,伪操作,语法格式,作 用,ASSERT,ASSERT logical expression,对汇编程序的第二遍扫描中,如果其中,ASSERT,中条件不成立,,ASSERT,伪操作将报告该错误信息。,INFO,INFO numeric-expression,,,string-expression,在汇编处理过程的第一遍扫描或者第二遍扫描时,INFO,伪操作报告诊断信息。,OPT,OPT n,通过,OPT,伪操作可以在源程序中设置列表选项。,TTL,TTL title,在列表文件的每一页的开头插入一个标题。,SUBT,SUBT subtitle,在列表文件的每一页的开头插入一个子标题。,伪操作,语法格式,作 用,CODE16,CODE16,告诉汇编编译器后面的指令序列为,16,位的,Thumb,指令,CODE32,CODE32,告诉汇编编译器后面的指令序列为,32,位的,ARM,指令。,EQU,name EQU expr,,,type,为数字常量、基于寄存器的值和程序中的标号(基于,PC,的值)定义一个字符名称,类似于,C,语言中的,define,宏定义。,AREA,AREA sectionname,,,attr,,,attr,定义一个代码段或者数据段。,ENTRY,ENTRY,指定程序的入口点。,END,END,告诉编译器已经到了源程序结尾。,ALIGN,ALIGN,expr,,,offset,通过添加补丁字节使当前位置满足一定的对齐方式。,EXPORT/ GLOBAL,EXPORT symbol,WEAK,声明一个符号可以被其他文件引用,.,IMPORT,IMPORT symbol,WEAK,告诉编译器当前的符号不是在本源文件中定义的,而是在其他源文件中定义的,在本源文件中可能引用该符号。,EXTERN,EXTERN symbol,WEAK,告诉编译器当前的符号不是在本源文件中定义的,而是在其他源文件中定义的,在本源文件中可能引用该符号。,GET/ INCLUDE,GET filename,将一个源文件包含到当前源文件中,并将被包含的文件在其当前位置进行汇编处理。,INCBIN,INCBIN filename,将一个文件包含到当前源文件中,被包含的文件不进行汇编处理。,KEEP,KEEP,symbol,告诉编译器将局部符号包含在目标文件的符号表中。,NOFP,NOFP,禁止源程序中包含浮点运算指令。,REQUIRE,REQUIRE lable,指定段之间的相互依赖关系。,RN,name RN expr,为一个特定的寄存器定义名称。,ROUT,name ROUT,定义局部变量的有效范围。,4.1.3 GNU,编译环境下的伪操作和宏指令,GNU,编译环境下的伪操作可分为以下几类:,常量编译控制伪操作,汇编程序代码控制伪操作,宏及条件编译控制伪操作,其他伪操作,常量编译控制伪操作,:,伪操作,语法格式,作 用,.byte,.byte expr ,,,expr ,分配一段字节内存单元,并用,expr,初始化。,.hword/.short,.hword expr ,,,expr ,分配一段半字内存单元,并用,expr,初始化。,.ascii,.ascii expr ,,,expr ,定义字符串,expr,(非零结束符)。,.asciz /.string,.asciz expr ,,,expr ,定义字符串,expr,(以,/0,为结束符)。,.float/.single,.float expr ,,,expr ,定义一个,32bit IEEE,浮点数,expr,。,.double,.double expr ,,,expr ,定义,64bit IEEE,浮点数,expr,。,word/.long /.int,.word expr ,,,expr ,分配一段字内存单元,并用,expr,初始化。,.fill,.fill repeat ,,,size,,,value,分配一段字节内存单元,用,size,长度,value,填充,repeat,次。,.zero,.zero size,分配一段字节内存单元,并用,0,填充内存。,.space/.skip,.space size , value,分配一段内存单元,用,value,将内存单元初始化。,汇编程序代码控制伪操作,伪操作,语法格式,作 用,.section,.section expr,定义域中包含的段。,.text,.text subsection,将操作符开始的代码编译到代码段或代码段子段。,.data,.data subsection,将操作符开始的数据编译到数据段或数据段子段。,.bss,.bss subsection,将变量存放到,.bss,段或,.bss,段的子段。,.code 16/.thumb,.code 16,.thumb,表明当前汇编指令的指令集选择,Thumb,指令集。,.code 32/.arm,.code 32,.arm,表明当前汇编指令的指令集选择,ARM,指令集。,.end,.end,标记汇编文件的结束行,即标号后的代码不作处理。,.include,.include,“,filename,”,将一个源文件包含到当前源文件中。,.align/.balign,.align alignment ,,,fill ,,,max,通过添加填充字节使当前位置满足一定的对齐方式。,宏及条件编译控制伪操作,伪操作,语法格式,作 用,.macro,、,.,exitm,及,.endm,.macro acroname,parameter,,,parameter,.endm,.macro,伪操作标识宏定义的开始,,.endm,标识宏定义的结束。用,.macro,及,.endm,定义一段代码,称为宏定义体。,.exitm,伪操作用于提前退出宏。,. ifdef,,,.else,及,.endif,.ifdef condition,.else,.endif,当满足某条件时对一组语句进行编译,而当条件不满足时则编译另一组语句。其中,else,可以缺省。,其他伪操作,伪操作,语法格式,作 用,.eject,.eject,在汇编符号列表文件中插入一分页符。,.list,.list,产生汇编列表(从,.list,到,.nolist,)。,.nolist,.nolist,表示汇编列表结束处。,.title,.title “heading”,使用“,heading ”,作为标题。,.sbttl,.sbttl “heading”,使用“,heading”,作为子标题。,.ltorg,.ltorg,在当前段的当前地址(字对齐)产生一个文字池。,.req,.req name,,,expr,为一个特定的寄存器定义名称。,.err,.err,使编译时产生错误报告。,.print,.print string,打印信息到标准输出。,.fail,.fail expr,编译汇编文件时产生警告。,4.1.4ARM,汇编语言的伪指令,伪指令,语法格式,作 用,ADR,ADR,cond,register,,,expr,将基于,PC,或基于寄存器的地址值读取到寄存器中。小范围的地址读取。,ADRL,ADRL,cond,register,,,expr,将基于,PC,或基于寄存器的地址值读取到寄存器中。中等范围的地址读取。,LDR,LDR,cond,register,,,=,expr | label-expr,将一个,32,位的立即数或者一个地址值读取到寄存器中。大范围的地址读取。,NOP,NOP,在汇编时将被替换成,ARM,中的空操作。,4.2.1ARM,汇编中的文件格式,ARM,源程序文件(可简称为源文件)可以由任意一种文本编辑器来编写程序代码,它一般为文本格式。在,ARM,程序设计中,常用的源文件可简单分为以下几种,:,源程序文件,文件名,说,明,汇编程序文件,*.S,用,ARM,汇编语言编写的,ARM,程序或,Thumb,程序。,C,程序文件,*.C,用,C,语言编写的程序代码,。,头文件,*.H,为了简化源程序,把程序中常用到的常量命名、宏定义、数据结构定义等等单独放在一个文件中,一般称为头文件。,4.2.2 ARM,汇编语言语句格式,ARM,汇编语言语句格式如下所示:,symbol,instruction | directive | pseudo-instruction,;,comment,其中:,instruction,为指令。,directive,为伪操作。,pseudo-instruction,为伪指令。,symbol,为符号。,comment,为语句的注释。,ARM,汇编语言程序格式,ARM,汇编语言是以段(,section,)为单位来组织源文件的。段是相对独立的、具有特定名称的、不可分割的指令或者数据序列。段又可以分为代码段和数据段,代码段存放执行代码,数据段存放代码运行时需要用到的数据。一个,ARM,源程序至少需要一个代码段,大的程序可以包含多个代码段和数据段。,举例说明,ARM,汇编语言源程序的基本结构,AREA EXAMPLE,,,CODE,,,READONLY,ENTRY,start,MOV r0,,,#10,MOV r1,,,#3,ADD r0,,,r0,,,r1,END,本程序的程序体部分实现了一个简单的加法运算。,4.2.3ARM,汇编语言编程的重点,ARM,数据处理操作,设置条件码,汇编语言子程序调用及返回,跳转表思想,ARM,与,Thumb,之间的状态转换及函数的相调用,ARM,数据处理操作,ARM,中数据的处理有以下三种形式:,简单的寄存器操作,立即数操作,寄存器移位操作,其中,32,位立即数在,32,位指令中的编码以及,ARM,特有的寄存器移位操作是数据处理方面的难点。,设置条件码,ARM,的任何数据处理指令都能通过增加,“,S”,操作码来设置条件码(,N,,,Z,,,C,和,V,),。,条件执行,ARM,指令集不同寻常的特征是每条指令(除了某些,v5T,指令)都可以是条件执行的。,条件转移,在程序中,可以通过条件码的使用让,微处理器决定是否进行转移,还可用来控制循环的退出。,汇编语言子程序调用及返回,子程序的调用,在,ARM,汇编语言中,子程序调用是通过,BL,指令来完成的。,BL,指令的语法格式如下:,BL,subname,其中,,subname,是被调用的子程序的名称。,子程序的返回,在返回调用子程序时,转移链接指令保存到,LR,寄存器(,r14,)中的值需要拷贝回程序寄存器,PC,(,r15,)。,跳转表思想,在程序设计中,有时为使程序完成一定的功能,需要调用一系列子程序中的一个,而决定究竟调用哪一个由程序的计算值确定。跳转表是解决该问题的有效方案。跳转表是利用程序计数器,PC,在通用寄存器文件中的可见性来实现的,如下例所示:,ARM,与,Thumb,间的状态转换及函数的相调用,状态切换的实现,ARM/Thumb,之间的状态切换是通过一条专用的转移交换指令,BX,来实现的。,BX,利用,Rn,寄存器中目的地址值的最后一位来判断跳转后的状态。当最后一位为,0,时,表示转移到,ARM,状态;当最后一位为,1,时,表示转移到,Thumb,状态,如下图所示。,ARM,与,Thumb,间的状态转换及函数的相调用,ARM/Thumb,之间的函数调用,在同一状态下的子程序调用,通常只需要一条指令实现调用:,BL function,实现返回也只需要从,LR,恢复,PC,即可:,MOV PC,,,LR,在不同状态下的子程序调用中,就需要进行状态之间的切换,需要考虑到以下几点:,需要由,BX,来切换状态,因为,BL,不能完成状态切换。,需要在,BX,之前先保存好,LR,,,BX,不能自动保存返回地址到,LR,。,需要,用,“,BX LR”,来返回,不能使用,“,MOV PC,,,LR”,,返回时要仔细考虑保存在,LR,中最低位的内容是否正确。,4.3.1 C,语言“,预处理伪指令,”,在嵌入式程序设计中的应用,“,预处理命令,”,可以改进程序设计的环境,提高编程效率,一般以,#,号打头 ,可分为以下三种 :,文件包含,宏定义,条件编译,文件包含,文件包含伪指令可将头文件包含到程序中,头文件中定义的内容包括符号常量、复合变量原型、用户定义的变量类型原型和函数的原型说明等。编译器编译预处理时用文件包含的正文内容替换到实际程序中。,文件包含伪指令的格式,#include,;,标准头文件,#include“,头文件名,.h”,;自定义头文件,#include,宏标识符,宏定义,宏定义伪指令分为:简单宏、参数宏、条件宏、预定义宏及宏释放。,简单宏,:,# define,宏标识符 宏体,参数宏:,# define,宏标识符(,形式参数表),宏体,条件宏定义:,#ifdef,宏标识符,#ifndef,宏标识符,#undef,宏标识符,#define,宏标识符 宏体,#define,宏标识符 宏体,#else,#else#undef,宏标识符,#define,宏标识符 宏体,#define,宏标识符 宏体,#endif#endif,条件编译,条件编译伪指令是写给编译器的,指示编译器在满足某一条件时仅编译源文件中与之相应的部分。其格式如右框中所示:,#if,(条件表达式,1,),#elif,(条件表达式,2,),#elif,(条件表达式,n,),#else,#endif,4.3.2,嵌入式程序设计中的函数及函数库,函数是,C,语言程序设计的核心。一个较大的,C,语言程序一般是由一个主函数和若干个子函数组成,每个函数完成一个特定的功能。函数之间也可以相互调用。,函数的格式,:,定义性说明格式 :,存储类说明符,类型说明符 修饰符 标识符 (参数表),函数体,原型说明格式 :,extern,类型说明符,修饰符,标识符(参数表)函数体,嵌入式程序设计中的函数及函数库,函数库是为了减少编程工作量,将一些常用的功能的函数放在函数库中供公共使用,.,它包括,C,的标准库函数,也包括一些用户自己编写非标准库。,例如,,44,blib.h,是根据基于,S3C44B0X,处理器的开发板及其功能模块编写的一个,C,语言函数库。它不属于,C,语言的标准库。,4.3.3,嵌入式程序设计中常用的,C,语言语句,C,语言语句格式为:,标号:,语句,;,C,语言语句很多,,常用到的有以下几种:,条件语句,swith,语句,循环语句,4.3.4,嵌入式程序设计中,C,语言的变量、,数组、结构、联合,变量,存储类型,类型说明符,修饰符,标识符,初值, ,,标识符,初值,;,数组,一维数组:,类型说明符 标识符,常量表达式,初值,初值,,;,char,标识符, =,“,字符串,”,;,二维数组:,类型说明符 标识符,mn ,初值表,初值表,;,指针数组和数组指针,类型说明符 *标志符,常量表达式, =,地址,地址,,;,类型说明符 (*标志符), =,数组标识符,;,结构说明,存储类说明符, struct ,结构原型名,类型说明标识符,,标识符,;,类型说明标识符,,标识符,;,标识符,=,初值表, ,,标识符,=,初值表,;,联合说明,存储类说明符, union,联合原型名,类型说明符 标识符,,标识符,;,类型说明符 标识符,,标识符,;,标识符,=,初值表,,标识符,初值表,;,4.4,嵌入式,C,语言程序设计实例,5.4.1,嵌入式,C,语言程序编写的简单构架,5.4.2 Flash,测试代码介绍,程序源代码介绍,整个测试程序主文件,main.c,的代码构成图如下图所示,由,BootLoader,启动程序进入,C,语言主函数,main(),入口。,4.4.2,嵌入式,C,语言程序编写的简单构架,#include,预,编译指令,个,C,语言代码,一般要用,#include,编译指令将所需要的头文件加到该程序中,这是很有必要的,尤其是对编写较大的程序代码时。随后是定义一些外部变量,并对程序中的函数进行声明。,主函数,main,()的编写;,在每一个,C,语言代码中,一定要有一个,main,()函数,在该函数中完成该程序文件所要完成的各个功能,一般是通过调用各个子函数来完成。当然,它也可以调用其他文件中的函数。,完成相应功能的各个功能函数的编写。,各个函数之间可以相互调用。,4.4.3 Flash,测试代码介绍,下面给出,功能测试程序中,Flash,测试程序的代码结构图:,4.5.1,变量定义,在变量声明的时候,最好把所有相同类型的变量放在一起定义,这样可以优化存储器布局。,由下例可以看出:,对于局部变量类型的定义,使用,short,或,char,来定义变量并不是总能节省存储空间。有时使用,32,位,int,或,unsinged int,局部变量更有效率一些,如下图所示:,变量定义中,为了精简程序,程序员总是竭力避免使用冗余变量。但有时使用冗余变量可以减少存储器访问的次数这可以提高系统性能。,4.5.2,参数传递,为了使单独编译的,C,语言程序和汇编程序能够互相调用,定义了统一的函数过程调用标准,ATPCS,。,ATPCS,定义了寄存器组中的,R0R3,作为参数传递和结果返回寄存器,如果参数数目超过四个,则使用堆栈进行传递。,内部寄存器的访问速度是远远大于存储器的,所以要尽量使参数传递在寄存器里面进行,即应尽量把函数的参数控制在四个以下。,4.6.1ATPCS,介绍,ATPCS,(,ARM-Thumb Produce Call Standard,)是,ARM,程序和,Thumb,程序中子程序调用的基本规则,目的是为了使单独编译的,C,语言程序和汇编程序之间能够相互调用。这些基本规则包括子程序调用过程中寄存器的使用规则、数据栈的使用规则和参数的传递规则。,寄存器的使用规则,:,寄存器,别名,特殊名,使用规则,R0,a1,参数,/,结果,scratch,寄存器,1,R1,a2,参数,/,结果,scratch,寄存器,2,R2,a3,参数,/,结果,scratch,寄存器,3,R3,a4,参数,/,结果,scratch,寄存器,4,R4,v1,ARM,状态局部变量寄存器,1,R5,v2,ARM,状态局部变量寄存器,2,R6,v3,ARM,状态局部变量寄存器,3,R7,v4,wr,ARM,状态局部变量寄存器,4,Thumb,状态工作寄存器,R8,v5,ARM,状态局部变量寄存器,5,R9,v6,sb,ARM,状态局部变量寄存器,6,,,在支持,RWPI,的,ATPCS,中为静态基址寄存器,R10,v7,sl,ARM,状态局部变量寄存器,7,,,在支持数据栈检查的,ATPCS,中为数据栈限制指针,R11,v8,fp,ARM,状态局部变量寄存器,8/,帧指针,R12,ip,子程序内部调用的,scratch,寄存器,R13,sp,数据栈指针,R14,lr,连接寄存器,R15,pc,程序计数器,数据栈的使用规则,根据堆栈指针指向位置的不同,和,增长方向的不同可以分为以下,4,种数据栈,:,FD,(,Full Descending,),满递减,ED,(,Empty Descending,)空递减,FA,(,Full Ascending,),满递增,EA,(,Empty Ascending,),空递增,ATPCS,规定数据栈为,FD,(满递减)类型,并且对数据栈的操作是,8,字节对齐的。,参数的传递规则,参数个数固定的子程序参数传递规则:,第一个整数参数,通过寄存器,R0,R3,来传递。其他参数通过数据栈传递。,参数个数可变的子程序参数传递规则:,当参数不超过,4,个时,可以使用寄存器,R0R3,来传递参数;当参数超过,4,个时,还可以使用数据栈来传递参数,子程序结果返回规则,结果为一个,32,位的整数时,可以通过寄存器,R0,返回;结果为一个,64,位整数时,可以通过寄存器,R0,和,R1,返回,依次类推。,4.6.2,内嵌汇编,在,C,程序中嵌入汇编程序可以实现一些高级语言没有的功能,并可以提高执行效率。,armcc,和,armcpp,内嵌汇编器支持完整的,ARM,指令集;,tcc,和,tcpp,用于,Thumb,指集。,内嵌的汇编指令包括大部分的,ARM,指令和,Thumb,指令,但是不能直接引用,C,的变量定义,数据交换必须通过,ATPCS,进行。嵌入式汇编在形式上表现为独立定义的函数体。,内嵌汇编指令的语法格式,_asm,(,“,指令,;指令,”,);,ARM C,汇编器使用关键字,“,_asm,。如果有多条汇编指令需要嵌入,可以用,“,”,将它们归为一条语句。如:,_asm,指令;指令,指令,需要特别注意的是,_asm,是两个下划线。,内嵌的汇编指令的特点,操作数可以是寄存器、常量或,C,表达式。它们可以是,char,、,short,或者,int,类型,而且是作为无符号数进行操作,。,内嵌的汇编指令中使用物理寄存器有一些限制。,常量前的符号,“,#,”,可以省略,只有指令,B,可以使用,C,程序中的标号,指令,BL,不能使用,C,程序中的标号。,不支持汇编语言中用于内存分配的伪操作。,指令中如果包含常量操作数,该指令可能会被汇编器展开成几条指令。,内嵌汇编器与,armasm,汇编器的区别,内嵌汇编器不支持通过,“,”,指示符或,PC,获取当前指令地址;,不支持,LDR,Rn,,,= expression,伪指令,而使用,MOV,Rn,,,expression,指令向寄存器赋值;,不支持标号表达式;,不支持,ADR,和,ADRL,伪指令;,不支持,BX,和,BLX,指令;,不可以向,PC,赋值;,使用,0x,前缀替代,“,”,表示十六进制数。,内嵌汇编注意事项,必须小心使用物理寄存器,如,R0R3,,,LR,和,PC,。,不要使用寄存器寻址变量。,使用内嵌汇编时,编译器自己会保存和恢复它可能用到的寄存器,用户无须保存和恢复寄存器。,LDM,和,STM,指令的寄存器列表只允许物理寄存器。,汇编语言用,“,,,”,作为操作数分隔符,4.6.3 C,和,ARM,汇编程序间相互调用,在,C,和,ARM,汇编程序之间相互调用必须遵守,ATPCS,(,ARM-Thumb Procedure Call Standard,)规则。,C,和汇编之间的相互调用可以从以下这三方面来介绍:,汇编程序对,C,全局变量的访问,在,C,语言程序中调用汇编程序,在汇编程序中调用,C,语言程序,汇编程序访问全局,C,变量,汇编程序可以通过地址间接访问在,C,语言程序中声明的全局变量。通过使用,IMPORT,关键词引人全局变量,并利用,LDR,和,STR,指令根据全局变量的地址可以访问它们。,对于不同类型的变量,需要采用不同选项的,LDR,和,STR,指令,如下所示:,unsigned charLDRB/STRB,unsigned shortLDRH/STRH,unsigned int LDR/STR,char LDRSB/STRSB,short LDRSH/STRSH,在,C,语言程序中调用汇编程序,为了保证程序调用时参数的正确传递,汇编程序的设计要遵守,ATPCS,。在汇编程序中需要使用,EXPORT,伪操作来声明,使得本程序可以被其它程序调用。同时,在,C,程序调用该汇编程序之前需要在,C,语言程序中使用,extern,关键词来声明该汇编程序。,在汇编程序中调用,C,语言程序,为了保证程序调用时参数的正确传递,汇编程序的设计要遵守,ATPCS,。在,C,程序中不需要使用任何关键字来声明将被汇编语言调用的,C,程序,但是在汇编程序调用该,C,程序之前需要在汇编语言程序中使用,IMPORT,伪操作来声明该,C,程序。在汇编程序中通过,BL,指令来调用子程序。,
展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 图纸专区 > 小学资料


copyright@ 2023-2025  zhuangpeitu.com 装配图网版权所有   联系电话:18123376007

备案号:ICP2024067431-1 川公网安备51140202000466号


本站为文档C2C交易模式,即用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知装配图网,我们立即给予删除!