资源预览内容
第1页 / 共52页
第2页 / 共52页
第3页 / 共52页
第4页 / 共52页
第5页 / 共52页
第6页 / 共52页
第7页 / 共52页
第8页 / 共52页
第9页 / 共52页
第10页 / 共52页
亲,该文档总共52页,到这儿已超出免费预览范围,如果喜欢就下载吧!
资源描述
汇编程序设计及混合汇编华清远见ARM汇编语言设计v汇编程序设计规范vIAR汇编器支持的伪指令v简单汇编语言程序设计华清远见汇编程序设计v特别说明: 开发工具不同, 所以的汇编语言伪 指令不同如: ADS vs IAR华清远见汇编语言程序设计规范段v段:相对独立的指令或数据序列, 具有特定的名称v段:v多个段在程序编译链接时最终形成 一个可执行的代码段代码段:内容为执行代码数据段:存放代码运行时需要用 到的数据华清远见段的设置规则v一个或多个代码段,代码段的属性 为只读v0个或多个包含初始化数据的数据段,数据段的属性为可读/写v0个或多个不包含初始化数据的数 据段,数据段的属性为可读/写华清远见注意v源文件中,段之间的相对位置与可 执行的映像文件中段的相对位置可 能不相同RORWZIROCODERO-DATARO-CODEAB华清远见简单的ARM汇编程序PROGRAM ASM_EXAMPL;第1行RSEG CODE:CODE:ROOT(2).;第2行CODE32ORG 0x1000 start: LDR R0,=0x3FF5000LDR R1,=0xFFSTR R1,R0MOV R0,#0x10MOV R1,#0x03ADD R0,R0,R1 stop: B STOPENDMODEND华清远见伪指令语法格式v汇编语言格式v符号v常量标号: 指令 操作数 ;注释十进制数:123,456十六进制数:0x123,0FFFFJ八进制数:1234q二进制数:1010b华清远见汇编语言程序设计v汇编程序设计规范vIAR汇编器支持的伪指令v简单汇编语言程序设计华清远见IAR汇编器支持的伪指令v模块控制伪指令v符号控制伪指令v模式控制伪指令v段定义伪指令v赋值伪指令v条件汇编伪指令v宏处理伪指令v数据定义伪指令v汇编控制伪指令 vC语言风格预处理伪指令华清远见模块控制伪指令伪伪指令说说明END结束汇编ENDMOD结束当前汇编LIBRARY定义多模块程序中的每个小模 块,用于创建库NAME定义程序模块RTMODEL 声明运行模式属性华清远见符号控制伪指令伪伪指令说说明EXTERN导入外部符号PUBLIC向其它模块导出符号REQUIRE强制引用符号华清远见模式控制伪操作伪伪指令说说明CODE16通知编译 器,其后的指令序列为16位 Thumb指令。在此范围内标号的位0被置1 ,强制2字节对齐CODE32通知编译 器,其后的指令序列为32位ARM 指令。在此范围内标号的位0被清0,强制4 字节对齐DATA在Thumb代码段内定义数据区华清远见段定义伪指令伪伪指令说说明ALIGNRAM以增量方式使存储器边界对齐ALIGNROM以填充0方式使存储器边界地址对齐ASEG定义绝对 段ASEGN定义指定绝对 段COMMON定义公共段EVEN将程序计数器按偶地址对齐ODD将程序计数器按奇地址对齐ORG设定起始地址RSEG定义可重定义段STACK定义堆栈段华清远见赋值伪指令伪伪指令说说明、ALIAS、 EQU定义模块内局部符号并永久赋值ASSIGN、SET 、SETA、VAR定义临时 符号并赋值DEFINE定义文件内全局符号并赋值 LIMIT超限检查华清远见条件汇编伪操作GBLL Test IF TEST=TRUE指令序列1ELSE指令序列2ENDIF华清远见宏处理伪指令伪伪指令说说明ENDM结束宏定义MACRO定义宏ENDR结束重复结构REPT对指令重复汇编EXITM提前退出宏LOCAL重复并替换字节REPTC定义宏中的局部变量REPTI重复并替换字符串华清远见数据定义伪指令伪伪指令说说明DC8、DCB产生8位字节常数,包括字符串DC16、DCW产生16位半字常数,包括字符串DC24产生24位常数DC32、DCD产生32位常数DF32、DF64分别产 生32位和64位浮点数DS8、DS16、 DS24,DS32分别保留8位字节,16位半字,24位字和 32位字的存储空间华清远见汇编控制伪指令伪伪指令说说明$,INCLUDE包含文件CASEON禁止对大小写字符敏感CASEOFF允许对大小写字符敏感LTORG声明文字池RADIX声明默认数制华清远见混合使用C/C+/汇编vv内联汇编和嵌入型汇编的使用内联汇编和嵌入型汇编的使用v从汇编代码访问 C 全局变量v在C+中使用C头文件vC、C+ 和 ARM 汇编语言之间的调用 华清远见什么地方会用到汇编v开机时硬件系统的初始化,包括CPU 状态的设 定,中断的使能,主频的设定,以及RAM 的控 制参数及初始化,中断处理方面也可能涉及汇 编。v一些对性能非常敏感的代码块,这是不能依靠 C 编译器的生成代码,而要手工编写汇编,达 到优化的目的。v操作系统移植华清远见何时使用内联汇编和嵌入型汇编v程序中使用饱和算术运算(Saturating arithmetic),如SSAT16 和 USAT16指令。v 程序中需要对协处理器进行操作。v 在C或C+程序中完成对程序状态寄存器的操作 注:使用内联汇编编写的程序代码效率也比较高 华清远见相互调用必须遵循ATPCSr8 r9/sb r10/sl r11r12r13/sp r14/lr r15/pcr0 r1 r2 r3r4 r5 r6 r7寄存器变量 必须保护作为函数传递的参数值Scratch register (corruptible)Stack Pointer Link Register Program Counter编译器使用一套规则来设置寄存器的用法CPSR 标志位可被函数调用所破坏 一些和编译过的代码交互工作的汇编码在接口层必 须满足的规范Register- 如果 RWPI选项有效,作为栈的基地址 - 如果软件堆栈检查有效,作为栈的限制值- r14值压栈以后,r14可作为一个临时寄存器使用华清远见在C程序中调用汇编v在汇编程序中用export name来定 义 v在C程序中直接调用v一般的链接即可 extern void mystrcopy(char *d, const char *s); int main(void) const char *src = “Source”;char dest10; .mystrcopy(dest, src);.AREA StringCopy, CODE, READONLYEXPORT mystrcopymystrcopyLDRB r2, r1, #1STRB r2, r0, #1CMP r2, #0BNE mystrcopyMOV pc, lrEND这里所有的参数都是可以用寄存器来传递的,所以不需要在汇编程序中使用 PUSH/POP来保护CALL华清远见内联汇编的特点1 由于内联汇编嵌入在C或C+程序中,所有在用法上有其自身 的一些特点。 如果同一行中包含多条指令,则用分号隔开。 如果一条指令不能在一行中完成,使用反斜杠“/”将其连接 。 内联汇编中的注释语句可以使用C或C+风格的。 汇编语言中使用逗号“,”作为指令操作数的分隔符,所以 如果在C语言中使用逗号必须用圆括号括起来。如,_asm ADD x, y, (f(), z)。 内联汇编语言中的寄存器名被编译器视为C或C+语言中的 变量,所以内联汇编中出现的寄存器名不一定和同名的物 理寄存器相对应。而且这些寄存器名在使用前必须声明, 否则编译器将提示警告信息。 内联汇编中的寄存器(除程序状态寄存器CPSR和SPSR外) 在读取前必须先赋值,否则编译器将产生错误信息。 华清远见内联汇编与汇编之间的区 别错误的内联汇编函数如下所示。int f(int x)_asmSTMFD sp!, r0 / 保存r0 不合法,因为在读之前没有对 寄存器寄存器写操作ADD r0, x, 1EOR x, r0, xLDMFD sp!, r0 / 不需要 恢复寄存器.return x;将其进行改写,是它 符合内联汇编的语 法规则。int f(int x)int r0;_asmADD r0, x, 1EOR x, r0, xreturn x;华清远见内联汇编语法 _asm(“instruction;instruction“); / 必须为单条指令_asminstruction;instruction _asm.instruction. asm(“instruction;instruction“); / 必须为单条指令asminstruction;instruction asm.instruction.华清远见内联汇编( Inline assembler )v使用C变量代替寄存器 不是一个真正的汇编文 件 通过优化器实现 代码可能被改变v只支持在ARM 模式 (not Thumb)v可以有自己独立的函数 ,但通常是内嵌在C函 数中/* Q flag is bit 27 of PSR */const int Q_Flag=0x08000000;_inline int Clear_Q_flag (void)int old_psr, new_psr, result;_asmMRS old_psr, CPSRBIC new_psr, old_psr, #Q_FlagAND result, old_psr, #Q_FlagMSR CPSR_f, new_psr return result;华清远见内联汇编的限制1可以在内联汇编代码中执行的操作有许多限制。这些限制提供安全的方法,并确保在汇编代码中不违反 C 和 C+ 代码编译中的规则。 不能直接向程序计数器PC赋值。 内联汇编不支持标号变量。 不能在程序中使用“.”或PC得到当前指令地址值。 在16进制常量前加“0x”。 建议不要对堆栈进行操作。华清远见内联汇编的限制2 编译器可能会使用r12和r13寄存器存放编译的中间结果,在计算表达式值可能会将寄存器r0r3、r12及r14用于子程序调用。另外在内联汇编中设置程序状态寄存器CPSR中的标志位NZCV时,要特别小心。内联汇编中的设置很可能会和编译器计算的表达式的结果冲突。 可以使用内联汇编代码更改处理器模式。然而,更改处理器模式会禁止使用 C或 C+ 操作数或对已编译 C 或 C+ 代码的调用,直到将处理器模式更改回原设置之后之前的函数库才可正常使用。 为 Thumb 状态编译 C 或 C+ 时,内联汇编程序不可用且不汇编 Thumb 指令。华清远见内联汇编的限制3 尽管可以使用通用协处理器指令指定 VFP 或 FPA 指令,但内联汇编程序不为它们提供直接支持。不能用内联汇编代码更改 VFP 向量模式。内联汇编可包含浮点表达式操作数,该操作数可使用编译程序生成的 VFP 代码求出操作数值。因此,仅由编译程序修改 VFP 状态很重要。 内嵌汇编不支持的指令:BX、BLX、BXJ和BKPT指令。而LDM、STM、LDRD和STRD指令可能被变形为等效的ARM LDR或STR指令华清远见内联汇编中的虚拟寄存器v内联汇编程序提供对 ARM 处理器物理寄存器的非直接访问。如果在内联汇编程序指令中将某个 ARM 寄存器用作操作数,它就成为相同名称的虚拟寄存器的引用,而不是对实际物理 ARM 寄存器的引用。例如内联汇编指令中使用了寄存器r0,但对于C编译器,指令中出现的r0只是一个变量,并非实际的物理寄存器r0,当程序运行时,可能是由物理寄存器r1来存放r0所代表的值。华清远见内联汇编中虚拟寄存器举 例#include void test_inline_register(void) int i;int r5,r6,r7;_asmMOV i,#0lo
网站客服QQ:2055934822
金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号