汇编程序设计以及混合汇编教学课件

上传人:仙*** 文档编号:241540330 上传时间:2024-07-03 格式:PPT 页数:52 大小:206.50KB
返回 下载 相关 举报
汇编程序设计以及混合汇编教学课件_第1页
第1页 / 共52页
汇编程序设计以及混合汇编教学课件_第2页
第2页 / 共52页
汇编程序设计以及混合汇编教学课件_第3页
第3页 / 共52页
点击查看更多>>
资源描述
汇编程序设计及混合汇编2020/12/111华清远见华清远见ARM汇编语言设计v汇编程序设计规范汇编程序设计规范vIAR汇编器支持的伪指令v简单汇编语言程序设计2020/12/112华清远见华清远见汇编程序设计v特别说明:开发工具不同,所以的汇编语言伪指令不同 如:ADS vs IAR2020/12/113华清远见华清远见汇编语言程序设计规范段v段:相对独立的指令或数据序列,具有特定的名称v段:v多个段在程序编译链接时最终形成一个可执行的代码段代码段:内容为执行代码数据段:存放代码运行时需要用到的数据2020/12/114华清远见华清远见段的设置规则v一个或多个代码段,代码段的属性为只读v0个或多个包含初始化数据的数据段,数据段的属性为可读/写v0个或多个不包含初始化数据的数据段,数据段的属性为可读/写2020/12/115华清远见华清远见注意v源文件中,段之间的相对位置与可执行的映像文件中段的相对位置可能不相同RORWZIROCODERO-DATARO-CODEAB2020/12/116华清远见华清远见简单的ARM汇编程序 PROGRAM ASM_EXAMPL.;第1行 RSEG CODE:CODE:ROOT(2).;第2行 CODE32 ORG 0 x1000start:LDR R0,=0 x3FF5000 LDR R1,=0 xFF STR R1,R0 MOV R0,#0 x10 MOV R1,#0 x03 ADD R0,R0,R1stop:B STOP ENDMOD END2020/12/117华清远见华清远见伪指令语法格式v汇编语言格式v符号v常量标号:指令 操作数 ;注释十进制数:123,456十六进制数:0 x123,0FFFFJ八进制数:1234q二进制数:1010b2020/12/118华清远见华清远见汇编语言程序设计v汇编程序设计规范vIAR汇编器支持的伪指令汇编器支持的伪指令v简单汇编语言程序设计2020/12/119华清远见华清远见IAR汇编器支持的伪指令v模块控制伪指令v符号控制伪指令v模式控制伪指令v段定义伪指令v赋值伪指令v条件汇编伪指令v宏处理伪指令v数据定义伪指令v汇编控制伪指令vC语言风格预处理伪指令2020/12/1110华清远见华清远见模块控制伪指令伪指令伪指令说明说明END结束汇编ENDMOD结束当前汇编LIBRARY定义多模块程序中的每个小模块,用于创建库NAME定义程序模块RTMODEL 声明运行模式属性2020/12/1111华清远见华清远见符号控制伪指令伪指令伪指令说明说明EXTERN导入外部符号PUBLIC向其它模块导出符号REQUIRE强制引用符号2020/12/1112华清远见华清远见模式控制伪操作伪指令伪指令说明说明CODE16通知编译器,其后的指令序列为16位Thumb指令。在此范围内标号的位0被置1,强制2字节对齐CODE32通知编译器,其后的指令序列为32位ARM指令。在此范围内标号的位0被清0,强制4字节对齐DATA在Thumb代码段内定义数据区2020/12/1113华清远见华清远见段定义伪指令伪指令伪指令说明说明ALIGNRAM以增量方式使存储器边界对齐ALIGNROM以填充0方式使存储器边界地址对齐ASEG定义绝对段ASEGN定义指定绝对段COMMON定义公共段EVEN将程序计数器按偶地址对齐ODD将程序计数器按奇地址对齐ORG设定起始地址RSEG定义可重定义段STACK定义堆栈段2020/12/1114华清远见华清远见赋值伪指令伪指令伪指令说明说明、ALIAS、EQU定义模块内局部符号并永久赋值ASSIGN、SET、SETA、VAR定义临时符号并赋值DEFINE定义文件内全局符号并赋值LIMIT超限检查2020/12/1115华清远见华清远见条件汇编伪操作GBLL TestIF TEST=TRUE 指令序列1ELSE 指令序列2ENDIF2020/12/1116华清远见华清远见宏处理伪指令伪指令伪指令说明说明ENDM结束宏定义MACRO定义宏ENDR结束重复结构REPT对指令重复汇编EXITM提前退出宏LOCAL重复并替换字节REPTC定义宏中的局部变量REPTI重复并替换字符串2020/12/1117华清远见华清远见数据定义伪指令伪指令伪指令说明说明DC8、DCB产生8位字节常数,包括字符串DC16、DCW产生16位半字常数,包括字符串DC24产生24位常数DC32、DCD产生32位常数DF32、DF64分别产生32位和64位浮点数DS8、DS16、DS24,DS32分别保留8位字节,16位半字,24位字和32位字的存储空间2020/12/1118华清远见华清远见汇编控制伪指令伪指令伪指令说明说明$,INCLUDE包含文件CASEON禁止对大小写字符敏感CASEOFF允许对大小写字符敏感LTORG声明文字池RADIX声明默认数制2020/12/1119华清远见华清远见混合使用C/C+/汇编v内联汇编和嵌入型汇编的使用内联汇编和嵌入型汇编的使用v从汇编代码访问 C 全局变量v在C+中使用C头文件vC、C+和 ARM 汇编语言之间的调用 2020/12/1120华清远见华清远见什么地方会用到汇编v开机时硬件系统的初始化,包括CPU 状态的设定,中断的使能,主频的设定,以及RAM 的控制参数及初始化,中断处理方面也可能涉及汇编。v一些对性能非常敏感的代码块,这是不能依靠C 编译器的生成代码,而要手工编写汇编,达到优化的目的。v操作系统移植2020/12/1121华清远见华清远见何时使用内联汇编和嵌入型汇编v程序中使用饱和算术运算(Saturating arithmetic),如SSAT16 和 USAT16指令。v 程序中需要对协处理器进行操作。v 在C或C+程序中完成对程序状态寄存器的操作 注:使用内联汇编编写的程序代码效率也比较高 2020/12/1122华清远见华清远见相互调用必须遵循ATPCSr8r9/sbr10/slr11r12r13/spr14/lrr15/pcr0r1r2r3r4r5r6r7寄存器变量寄存器变量必须保护必须保护作为函数传递的参数值作为函数传递的参数值Scratch register(corruptible)Stack PointerLink RegisterProgram Counter编译器使用一套规则来设置寄存器的用法CPSR 标志位可被函数调用所破坏一些和编译过的代码交互工作的汇编码在接口层必须满足的规范Register-如果如果 RWPI选项有效,作为栈的基地址选项有效,作为栈的基地址-如果软件堆栈检查有效,作为栈的限制值如果软件堆栈检查有效,作为栈的限制值-r14值压栈以后,值压栈以后,r14可作为一个临时寄存器使用可作为一个临时寄存器使用2020/12/1123华清远见华清远见在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,READONLY EXPORT mystrcopymystrcopy LDRB r2,r1,#1 STRB r2,r0,#1 CMP r2,#0 BNE mystrcopy MOV pc,lr END这里所有的参数都是可以用寄存器来传递的,所以不需要在汇编程序中使用PUSH/POP来保护CALL2020/12/1124华清远见华清远见内联汇编的特点1由于内联汇编嵌入在C或C+程序中,所有在用法上有其自身的一些特点。如果同一行中包含多条指令,则用分号隔开。如果一条指令不能在一行中完成,使用反斜杠“/”将其连接。内联汇编中的注释语句可以使用C或C+风格的。汇编语言中使用逗号“,”作为指令操作数的分隔符,所以如果在C语言中使用逗号必须用圆括号括起来。如,_asm ADD x,y,(f(),z)。内联汇编语言中的寄存器名被编译器视为C或C+语言中的变量,所以内联汇编中出现的寄存器名不一定和同名的物理寄存器相对应。而且这些寄存器名在使用前必须声明,否则编译器将提示警告信息。内联汇编中的寄存器(除程序状态寄存器CPSR和SPSR外)在读取前必须先赋值,否则编译器将产生错误信息。2020/12/1125华清远见华清远见内联汇编与汇编之间的区别错误的内联汇编函数如下所示。int f(int x)_asm STMFD sp!,r0 /保存r0 不合法,因为在读之前没有对寄存器寄存器写操作 ADD r0,x,1 EOR x,r0,x LDMFD sp!,r0 /不需要恢复寄存器.return x;将其进行改写,是它符合内联汇编的语法规则。int f(int x)int r0;_asm ADD r0,x,1 EOR x,r0,x return x;2020/12/1126华清远见华清远见内联汇编语法 _asm(instruction;instruction);/必须为单条指令 _asminstruction;instruction _asm .instruction .asm(instruction;instruction);/必须为单条指令 asminstruction;instruction asm .instruction .2020/12/1127华清远见华清远见内联汇编(Inline assembler)v使用C变量代替寄存器不是一个真正的汇编文件通过优化器实现代码可能被改变v只支持在ARM 模式(not Thumb)v可以有自己独立的函数,但通常是内嵌在C函数中/*Q flag is bit 27 of PSR*/const int Q_Flag=0 x08000000;_inline int Clear_Q_flag(void)int old_psr,new_psr,result;_asm MRS old_psr,CPSR BIC new_psr,old_psr,#Q_Flag AND result,old_psr,#Q_Flag MSR CPSR_f,new_psr return result;2020/12/1128华清远见华清远见内联汇编的限制1可以在内联汇编代码中执行的操作有许多限制。这些限制提供安全的方法,并确保在汇编代码中不违反 C 和 C+代码编译中的规则。不能直接向程序计数器PC赋值。内联汇编不支持标号变量。不能在程序中使用“.”或PC得到当前指令地址值。在16进制常量前加“0 x”。建议不要对堆栈进行操作。2020/12/1129华清远见华清远见内联汇编的限制2 编译器可能会使用r12和r13寄存器存放编译的中间结果,在计算表达式值可能会将寄存器r0r3、r12及r14用于子程序调用。另外在内联汇编中设置程序状态寄存器CPSR中的标志位NZCV时,要特别小心。内联汇编中的设置很可能会和编译器计算的表达式的结果冲突。可以使用内联汇编代码更改处理器模式。然而,更改处理器模式会禁止使用 C或 C+操作数或对已编译 C 或 C+代码的调用,直到将处理器模式更改回原设置之后之前的函数库才可正常使用。为 Thumb 状态编译 C 或 C+时,内联汇编程序不可用且不汇编 Thumb 指令。2020/12/1130华清远见华清远见内联汇编的限制3 尽管可以使用通用协处理器指令指定 VFP 或 FPA 指令,但内联汇编程序不为它们提供直接支持。不能用内联汇编代码更改 VFP 向量模式。内联汇编可包含浮点表达式操作数,该操作数可使用编译程序生成的 VFP 代码求出操作数值。因此,仅由编译程序修改 VFP 状态很重要。内嵌汇编不支持的指令:BX、BLX、BXJ和BKPT指令。而LDM、STM、LDRD和STRD指令可能被变形为等效的ARM LDR或STR指令2020/12/1131华清远见华清远见内联汇编中的虚拟寄存器v内联汇编程序提供对 ARM 处理器物理寄存器的非直接访问。如果在内联汇编程序指令中将某个 ARM 寄存器用作操作数,它就成为相同名称的虚拟寄存器的引用,而不是对实际物理 ARM 寄存器的引用。例如内联汇编指令中使用了寄存器r0,但对于C编译器,指令中出现的r0只是一个变量,并非实际的物理寄存器r0,当程序运行时,可能是由物理寄存器r1来存放r0所代表的值。2020/12/1132华清远见华清远见内联汇编中虚拟寄存器举例#include void test_inline_register(void)int i;int r5,r6,r7;_asm MOV i,#0 loop:MOV r5,#0 MOV r6,#0 MOV r7,#0 ADD i,i,#1 CMP i,#3 BNE loop int main(void)test_inline_register();printf(test inline registern);return 0;2020/12/1133华清远见华清远见输出结果 test_inline_register:0000807C E3A00000 MOV r0,#0 TEST_INLINE_REGISTER#12 loop:00008080 E1A00000 NOP TEST_INLINE_REGISTER#13 MOV r5,#0 00008084 E3A01000 MOV r1,#0 TEST_INLINE_REGISTER#14 MOV r6,#0 00008088 E3A02000 MOV r2,#0 TEST_INLINE_REGISTER#15 MOV r7,#0 0000808C E3A03000 MOV r3,#0 TEST_INLINE_REGISTER#16 ADD i,i,#1 00008090 E2800001 ADD r0,r0,#1 TEST_INLINE_REGISTER#17 CMP i,#3 00008094 E3500003 CMP r0,#3 00008098 0A000000 BEQ 0 x80a0 TEST_INLINE_REGISTER#18 BNE loop 0000809C EAFFFFF8 B 0 x8084 TEST_INLINE_REGISTER#21 000080A0 E12FFF1E BX r142020/12/1134华清远见华清远见内联汇编中的指令展开内联汇编代码中的 ARM 指令可能会在编译过程中扩展为几条指令。扩展取决于指令、指令中指定的操作数个数以及每个操作数的类型和值。通常,被扩展的指令有以下几种情况,含有常数操作的指令;LDM、STM、LDRD 和 STRD指令;乘法指令MUL被扩展为一系列的加法和移位指令。例:包含有常数操作的加法指令ADD r0,r0,#1023被编译器编译为如下两条指令ADD r0,r0,#1024SUB r0,r0,#12020/12/1135华清远见华清远见内联汇编使用举例1中断使能_inline void enable_IRQ(void)int tmp;_asm MRS tmp,CPSR BIC tmp,tmp,#0 x80 MSR CPSR_c,tmp _inline void disable_IRQ(void)int tmp;_asm MRS tmp,CPSR ORR tmp,tmp,#0 x80 MSR CPSR_c,tmp int main(void)disable_IRQ();enable_IRQ();2020/12/1136华清远见华清远见内联汇编举例2#define MUTEX_LOCKED 1023#define MUTEX_UNLOCKED 0_inline int this_task(void)int task_id=0;/*Get Fast Context Switch Task ID*/_asm MRC p15,0,task_id,c13,c0,0 return(task_id25);_inline int get_mutex(volatile int*lock_addr)int owner;/*Does anyone own lock at the moment?*/_asm SWP owner,MUTEX_LOCKED,lock_addr if(owner=MUTEX_UNLOCKED)/*No?Replace MUTEX_LOCKED with our task id*/*lock_addr=this_task();else if(owner!=MUTEX_LOCKED)/*Yes?And owner is a valid task id?*Put owners task id back*/*lock_addr=owner;return owner;Resulting code(-O2-Ospace):LDR r5,|L1.76|;&uart_mtx LDR r4,|L1.72|;#1023|L1.12|MOV r0,#0 x400 BL OS_sleep SWP r0,r4,r5 CMP r0,#0 MRCEQ p15,0 x0,r1,c13,c0,0 ASREQ r1,r1,#25 STREQ r1,r5,#0 BEQ|L1.52|CMP r0,r4 STRNE r0,r5,#0|L1.52|CMP r0,#0 BNE|L1.12|+extern volatile int uart_mtx=0;.do OS_sleep(1024);while(get_mutex(&uart_mtx);.2020/12/1137华清远见华清远见嵌入型汇编用 _asm或asm声明的函数可以有调用参数和返回类型。它们从 C 和 C+中调用的方式与普通 C 和 C+函数调用方式相同。嵌入式汇编函数语法是:_asm return-type function-name(parameter-list)/ARM/Thumb/Thumb2 assembler code instruction;instruction .instruction2020/12/1138华清远见华清远见嵌入型汇编举例#include _asm void my_strcpy(const char*src,const char*dst)loop LDRB r3,r0,#1 STRB r3,r1,#1 CMP r3,#0 BNE loop MOV pc,lrvoid main()const char*a=Hello world!;char b20;my_strcpy(a,b);printf(Original string:%sn,a);printf(Copied string:%sn,b);2020/12/1139华清远见华清远见内联汇编和内嵌汇编的区别功能功能 嵌入式汇编程序嵌入式汇编程序 内联汇编程序内联汇编程序 指令集指令集 ARM和Thumb仅支持ARM ARM汇编指令伪操汇编指令伪操作作支持不支持ARMv6指令集指令集 支持 仅支持媒体指令 C/C+表达式表达式 只支持常数表达式 完全支持 汇编代码是否优化汇编代码是否优化 无优化 完全优化 寄存器访问寄存器访问 使用指定的物理寄存器。还可以使用 PC、LR 和 SP 使用虚拟寄存器。不能使用PC、LR 和 SP寄存器 是否支持是否支持BKPT指令指令不直接支持不支持2020/12/1140华清远见华清远见混合使用C/C+/汇编v内联汇编和嵌入型汇编的使用v从汇编代码访问从汇编代码访问 C 全局变量全局变量v在C+中使用C头文件vC、C+和 ARM 汇编语言之间的调用 2020/12/1141华清远见华清远见在C中访问汇编全局变量v在汇编代码中访问C全局变量,只能通过地址间接访问全局变量。要访问全局变量,必须在汇编中使用 IMPORT 伪操作引入全局变量,然后将地址载入寄存器。可以根据变量的类型使用载入和存储指令访问该变量。2020/12/1142华清远见华清远见在C中访问汇编全局变量举例 PRESERVE8 AREA globals,CODE,READONLY EXPORT asmsubroutine IMPORT globvarasmsubroutine LDR r1,=globvar ;read address of globvar into ;r1 from literal pool LDR r0,r1 ADD r0,r0,#2 STR r0,r1 MOV pc,lr END2020/12/1143华清远见华清远见混合使用C/C+/汇编v内联汇编和嵌入型汇编的使用v从汇编代码访问 C 全局变量v在在C+中使用中使用C头文件头文件vC、C+和 ARM 汇编语言之间的调用 2020/12/1144华清远见华清远见在在C+中使用中使用C头文件头文件本节描述如何在 C+代码中使用 C 头文件。从 C+调用 C 头文件之前,C 头文件必须包含在 extern“C”命令中。包含以下两部分内容:在在C+中使用系统的中使用系统的C头文件;头文件;在在C+中使用自定义的中使用自定义的C头文件头文件。2020/12/1145华清远见华清远见包含系统C头文件1要包括标准的系统 C 头文件,如 stdio.h,不必进行任何特殊操作。只有使用extern C 命令,则有编译器自动包含标准 C 头文件。例如:#include int main()./C+代码 return 0;2020/12/1146华清远见华清远见包含系统C头文件2C+标准规定可以通过特定的 C+头文件获取 C 头文件。这些文件与标准 C 头文件一起安装,可以用常规方法进行引用。例如:#include int main()./C+代码 return 0;2020/12/1147华清远见华清远见在C+中使用自定义的C头文件 在#include 文件之前使用extern,如下例所示。/C+codeextern C#include my-header1.h#include my-header2.hint main()/.return 0;将 extern C 语句添加到头文件,如下例所示/*C header file*/#ifdef _cplusplus /*Insert start of extern C construct*/extern C#endif/*Body of header file*/#ifdef _cplusplus /*Insert end of extern C construct*/*The C header now be*/#endif /*included in either C or C+code.*/2020/12/1148华清远见华清远见混合使用C/C+/汇编v内联汇编和嵌入型汇编的使用v从汇编代码访问 C 全局变量v在C+中使用C头文件vC、C+和和 ARM 汇编语言之间的调汇编语言之间的调用用 2020/12/1149华清远见华清远见从 C 调用汇编语言#include extern void strcopy(char*d,const char*s);int main()const char*srcstr=First string-source;char dststr=Second string-destination;/*下面将dststr作为数组进行操作*/printf(Before copying:n);printf(%sn%sn,srcstr,dststr);strcopy(dststr,srcstr);printf(After copying:n);printf(%sn%sn,srcstr,dststr);return(0);PRESERVE8 AREA SCopy,CODE,READONLY EXPORT strcopystrcopy ;r0 points to destination string.;r1 points to source string.LDRB r2,r1,#1 ;Load byte and update address.STRB r2,r0,#1 ;Store byte and update address.CMP r2,#0 ;Check for zero terminator.BNE strcopy ;Keep going if not.MOV pc,lr ;Return.END2020/12/1150华清远见华清远见汇编语言调用C程序 int g(int a,int b,int c,int d,int e)return a+b+c+d+e;PRESERVE8 EXPORT f AREA f,CODE,READONLY IMPORT g ;声明C程序g()STR lr,sp,#-4!;保存返回地址 lr ADD r1,r0,r0 ;计算 2*i(第二个参数)ADD r2,r1,r0 ;计算 3*i(第三个参数)ADD r3,r1,r2 ;计算 5*i STR r3,sp,#-4!;第五个参数通过堆栈传递 ADD r3,r1,r1 ;计算 4*i(第四个参数)BL g ;调用C程序 ADD sp,sp,#4 ;从堆栈中删除第五个参数 LDR pc,sp,#4 ;返回 END2020/12/1151华清远见华清远见PPT教学课件谢 谢 观 看ThankYouForWatching52
展开阅读全文
相关资源
相关搜索

最新文档


当前位置:首页 > 管理文书 > 施工组织


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

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


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