- 1、本文档共51页,可阅读全部内容。
- 2、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
- 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 4、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
查看更多
C语言讲嵌入式C与汇编语言混合编程
【知识点】 LDM/STM指令的寄存器列表中只能使用物理寄存器不能使用C表达式 指令不能写寄存器PC 不支持指令BX/BLX 用户不要维护数据栈。通常编译器根据需要自动保存和恢复工作寄存器的值,而无需用户参与 * 【知识点】 在ARM C语言程序中使用关键词__asm来标识一段汇编指令程序: __asm { instruction [; instruction] …… [instruction] } 1)若一行中有多个汇编指令,指令间使用分号隔开 2)若一条指令占多行,要使用续行符号(\) 3)在汇编指令段中可以使用C语言的注释语句 * 【知识点】 在ARM C++程序中使用关键词__asm来标识一段汇编指令程序外,还可以使用关键词asm来标识一段汇编指令程序 asm(“instruction[;instruction]”); asm后面的括号中必须是一个单独的字符串;该字符串中不能包含注释语句 * 【知识点】 在汇编指令中,逗号(,)用作分隔符。因此如果指令中的C/C++表达式中包含有逗号(,),则该表达式应该被包含在括号中。 例: __asm {ADD x,y,(f(),z)} 其中(f(),z)为C/C++表达式 * 【知识点】 如果在指令中使用的物理寄存器,应该保证该寄存器不会被编译器在计算表达式值时破坏。如下代码段中,编译器通过程序调用来计算表达式x/y的值,在这个过程中编译器破坏了寄存器r2、r3、ip、lr的值,更新了CPSR寄存器的NZCV条件标志位;并在寄存器r0中返回表达式的商,在寄存器r1中返回表达式的余数。这时程序中寄存器r0的数据就丢了。 __asm { MOV r0,x ADD y,r0,x/y } __asm { MOV cvar,x //用c变量代替 ADD y,r0,x/y } * 【知识点】 由于编译器将会展开ADD指令,在展开时会用到ip寄存器,从而破坏了第一条指令为ip寄存器赋的值,这时编译器将报告错误。 例: __asm { MOV ip,#3 ADDS x,x,#0ORR x,x,ip } * 【知识点】 不要使用物理寄存器去引用一个C变量。例如在下例中用户可能认为进入子程序example1中后,参数x的值保存在寄存器r0中,因而在内嵌的汇编指令中直接使用寄存器r0,最后返回结果。实际上,编译器认为子程序中没有做任何有意义的操作,于是将该段汇编代码优化了,从而返回的结果与输入的参数值 相同,没有做加1操作 * 【知识点】 对于内嵌汇编器可能会用到的寄存器,编译器自己会保存和恢复这些寄存器,用户不用保存和恢复这些寄存器。常量寄存器CPSR和寄存器SPSR外,别的寄存器必须先赋值然后再读取,否则编译器将会报错。如下例中,第一条指令在没有给寄存器r0赋值前读取其值,是错误的;最后一条指令恢复寄存器r0的值,也是没有必要的 * 【知识点】 对于内嵌汇编器可能会用到的寄存器,编译器自己会保存和恢复这些寄存器,用户不用保存和恢复这些寄存器。常量寄存器CPSR和寄存器SPSR外,别的寄存器必须先赋值然后再读取,否则编译器将会报错。如下例中,第一条指令在没有给寄存器r0赋值前读取其值,是错误的;最后一条指令恢复寄存器r0的值,也是没有必要的 * 【知识点】 如何使用指令BL调用子程序。比起内嵌的SWI和BL指令,除了正常的操作数域外,还需要增加下面3个可选的寄存器列表: 第1个寄存器列表中的寄存器用于存放输入的参数 第2个寄存器列表中的寄存器用于存放返回的结果 第3个寄存器列表中的寄存器的内容可能被被调用的子程序破坏,即这些寄存器是供被调用的子程序作为工作寄存器的 * * 【知识点】 sum=a[0]*b[0]+a[1]*b[1]+……+a[9]*b[9]=220 * * 【知识点】 1、使用IMPORT伪操作声明该全局变量 2、使用LDR指令读取该全局变量的内存地址,通常该全局变量的内存地址值存放在程序的数据缓冲池中 3、根据该数据的类型,使用相应的LDR指令读取该全局变量的值;使用相应的STR指令修改该全局变量的值 * 【知识点】 1、对于无符号的char类型的变量通过指令LDRB/STRB来读/写 2、对于无符号的short类型的变量通过指令LDRH/STRH来读/写 3、对于int类型的变量通过指令LDR/STR读/写 4、对于有符号的char类型的变量通过指令LDRSB来读取 5、对于有符号的char类型的变量通过指令STRB来写入 * 【知识点】 5、对于有符号的short类型的变量通过指令LDRSH来读/写 6、对于有符号的short类型的变量通过指令STRH来写入 7、对于小于8个字的结构型变量,可以通过一条LDM/STM指
文档评论(0)