一般来说C比汇编语言好,但是
1、汇编调用C函数
汇编:
ldr pc,=gboot_main
C:
none
2、C调用汇编函数
汇编:
.global light_led
C:
light_led();
3、C内嵌汇编
和第二种方式不同,第二种方式汇编语句存放于单独的汇编文件中,而这种方式没有单独的汇编文件
3.1格式
其中破坏描述就是值被修改的寄存器都要列出来
破坏 可以理解为 修改
3、2范例
这里%0表示是一个参数,是我们的零号参数
虽然不知道这是不是r0,但是凡是我们要读的参数都要写到输入部分,p15_c1不是参数所以不用写
"r"指明这个参数的性质是通用寄存器,value表示这个通用寄存器的值,而这个寄存器是哪个我们不关心,系统随便给一个就行
=表明是只写的意思,只写入值
然后还要把寄存器r里面的值赋值给value
这里破坏部用到了memory,也就是内存被修改了。value局部变量存在于栈当中,被修改了,也就是内存被修改了
这里的注释符号还是用@,而不是//
3、3优化
一般处理器有可能会优化代码,比如
p1=0x01
p1=0x010
编译器会默认把前面的语句去掉。而在比如C51当中,这种输入很可能是实现某功能的要求输入序列,去掉功能不能实现
当有多行代码时需要没一行用引号括起来,再加上换行符
3、4修改代码,使用内嵌汇编实现点亮LED
首先复制进去,修改格式
然后去掉mov pc,lr。不需要回到主汇编当中
然后去掉ldr r0, =GPKCON ldr r0, =GPKDAT这两句,在输入部体现。
这两个参数我们都是读取它们的值作为地址输入到汇编中。
没有输出部,没有往某个参数里面去写入值。没有在汇编中被修改的C变量。破坏部因为会对r1寄存器造成影响,所以有破坏部
宏定义部分和上一节不一样,因为下面不再作为地址指针使用,而是直接在汇编中替换
#define GPKCON 0x7f008800
#define GPKDAT 0x7f008808
int gboot_main()
{
_asm_(
"ldr r1, =0x11110000\n"
"str r1, [%0]\n"
"ldr r1, =0xff\n"
"str r1, [%1]\n"
:
:"r"(GPKCON),"r"(GPKDAT)
:"r1");
return 0;
}