历史上的今天
今天是:2025年01月21日(星期二)
2021年01月21日 | 快速学Arm(11)--在C语言中内嵌汇编语言
2021-01-21 来源:eefocus
开发Arm程序的时候,大多数时候我们使用C/C++语言就可以了,但汇编语言在某些情况下能够实现一些C语言无法实现的功能,这时候就要调用一些汇编语言的程序.我们需要大概了解一下在C语言中如何嵌入汇编语言.
1.内嵌汇编语言的语法:
__asm
{
指令[;指令]
......
[指令]
}
2.举例:使能/禁止IRQ中断
__inline void enable_IRQ(void)
{
int tmp;
__asm //嵌入汇编代码
{
MRS tmp,CPSR //读取CPSR的值
BIC tmp,tmp,#0x80 //将IRQ中断禁止位I清零,即允许IRQ中断
MSR CPSR_c,tmp //设置CPSR的值
}
}
__inline void disable_IRQ(void)
{
int tmp;
__asm
{
MRS tmp,CPSR
ORR tmp,tmp,#Ox80
MSR CPSR_c,tmp
}
}
3.举例:字符串复制
void my-strcpy(const char *src,char *dst)
{
int ch;
__asm
{
loop:
#ifndef __thumb
LDRB ch,[src],#1
STRB ch,[dst],#1
#else
LDRB ch,[src]
ADD src,#1
STRB ch,[dst]
ADD dst,#1
#endif
CMP ch,#0
BNE loop
}
}
int main(void)
{
const char *a="Hello world!";
char b[20];
__asm
{
MOV R0,a
MOV R1,b
BL my_strcpy,{R0,R1}
}
return(0);
}
4.内嵌汇编的指令用法:
.操作书: 内嵌的汇编指令中作为操作数的寄存器和常量可以是C表达式.这些表达式可以是char,short或int等类型,而且这些表达式都是作为无符号数进行操作的.若要有符号数,用户需要自己处理与符号有关的操作.编译器将会计算这些表达式的值,并为其分配寄存器.
.物理寄存器:内嵌汇编中使用物理寄存器是有限制的:
_ 不能直接向PC(程序计数器)寄存器中赋值,程序跳转只能通过B或BL指令来实现.
_ 使用物理寄存器的指令中,不要使用过于复杂的C表达式
_ 尽可能少的使用物理寄存器
.常量: 在内嵌汇编指令中,常量前面的"#"可以省略
.标号: C程序中的标号可以被内嵌的汇编指令使用.但是只有指令B可以使用C程序中的标号,而指令BL则不能使用.
.内存单元的分配:所有内存分配均由C编译器完成,分配的内存单元通过变量供内嵌汇编器使用.内嵌汇编器不支持内嵌汇编程序中用于内存分配的伪指令.
5.内嵌汇编注意事项:
.必须小心使用物理寄存器,如R0~R3,IP,LR,CPSR中的标志位,避免发生冲突.
例如:
__asm
{
MOV R0,x
ADD y,R0,x/y
}
改成下面代码会比较妥当:
__asm
{
MOV var,x
ADD y,var,x/y
}
.不要使用寄存器代替变量.
.使用内嵌汇编无需保存和恢复寄存器.事实上,除了CPSR,SPSR寄存器,对物理寄存器先读后写都会引起汇编报错.
.汇编语言中","号作为操作数分隔符.如果有C表达式作为操作数,若表达式中包含有",",则必须使用()将其规约为一个汇编操作数,例如:
__asm
{
ADD x,y,(f(),z) //"f(),z"为带有","的C表达式.
}
6.不同数据类型对应的汇编指令:
unsigned char LDRB/STRB
unsigned short LDRH/STRH
unsigned int LDR/STR
char LDRSB/STRSB
short LDRSH/STRSH
7.访问C程序的变量:
AREA globals,CODE,READONLY
EXPORT asmsubroutine
IMPORT globalvar ;声明的外部变量
asmsubroutine
LDR R1,=blobalval
LDR R0,[R1]
ADD R0,R0,#1
STR R0,[R1]
MOV PC,LR
END
史海拾趣
|
作为局域网的主要连接设备,以太网交换机成为应用普及最快的网络设备之一,同时,也是随着这种快速的发展,交换机的功能不断增强,随之而来则是交换机端口的更新换代以及各种特殊设备连接端口不断的添加到交换机上,这也使得交换机的接口类型变得非 ...… 查看全部问答> |
|
本帖最后由 jameswangsynnex 于 2015-3-3 19:57 编辑 Job description: · Responsible for the creation, implementation and debugging of board level tests for Xbox accessories. · The test engineer must also be able to create d ...… 查看全部问答> |
|
大家好,68013的GPIO口一般是用8个端口(如P0-P7)接收8位数据,或16个端口(如P0-P15)接收16位数据,也就是第一个端口接收一位数据,现在我有另一个GPIO接口,只有一条线,输出的数据是以b0,b1~b7,这样的顺序,输完一个字节,又接着输第二个字节. 请问怎样才 ...… 查看全部问答> |




