Part10.4-C与汇编混合编程

时间:2021-11-05 12:09:27

一般来说C比汇编语言好,但是

Part10.4-C与汇编混合编程

 

 

Part10.4-C与汇编混合编程

1、汇编调用C函数

汇编:

  ldr pc,=gboot_main

C:

  none

 

2、C调用汇编函数

汇编:

  .global light_led

C:

   light_led();

 

3、C内嵌汇编

和第二种方式不同,第二种方式汇编语句存放于单独的汇编文件中,而这种方式没有单独的汇编文件

 

3.1格式

Part10.4-C与汇编混合编程

其中破坏描述就是值被修改的寄存器都要列出来

破坏 可以理解为 修改

Part10.4-C与汇编混合编程

 

 

3、2范例

 

 这里%0表示是一个参数,是我们的零号参数

虽然不知道这是不是r0,但是凡是我们要读的参数都要写到输入部分,p15_c1不是参数所以不用写

"r"指明这个参数的性质是通用寄存器,value表示这个通用寄存器的值,而这个寄存器是哪个我们不关心,系统随便给一个就行

Part10.4-C与汇编混合编程

 

=表明是只写的意思,只写入值

然后还要把寄存器r里面的值赋值给value

这里破坏部用到了memory,也就是内存被修改了。value局部变量存在于栈当中,被修改了,也就是内存被修改了

Part10.4-C与汇编混合编程

这里的注释符号还是用@,而不是//

 

3、3优化

 一般处理器有可能会优化代码,比如

p1=0x01

p1=0x010

编译器会默认把前面的语句去掉。而在比如C51当中,这种输入很可能是实现某功能的要求输入序列,去掉功能不能实现

Part10.4-C与汇编混合编程

 

 当有多行代码时需要没一行用引号括起来,再加上换行符

 

 

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;
}