ARM实例一

ARM实例一


  • 在u-boot基础上,编写一个程序实现用汇编语言调用自定义的函数

  • 带有C/C++表达式的内联汇编格式为:

__asm__ __volatile__("Instruction List" : Output : Input : Clobber/Modify);

其中每项的概念及功能用法描述如下:
1、__asm__
asm是GCC 关键字asm 的宏定义:

#define __asm__ asm

__asm__asm用来声明一个内联汇编表达式,所以任何一个内联汇编表达式都是以它开头的,是必不可少的。
2、Instruction List
Instruction List 是汇编指令序列。它可以是空的,比如:__asm__ __volatile__(""); 或 __asm__ ("");都是完全合法的内联汇编表达式,只不过这两条语句没有什么意义。但并非所有Instruction List 为空的内联汇编表达式都是没有意义的,比如:__asm__ ("":::"memory");
3. __volatile__
__volatile__是GCC 关键字volatile 的宏定义

#define __volatile__ volatile

__volatile__或volatile 是可选的。如果用了它,则是向GCC 声明不允许对该内联汇编优化,否则当 使用了优化选项(-O)进行编译时,GCC 将会根据自己的判断决定是否将这个内联汇编表达式中的指令优化掉。
4、 Output
Output 用来指定当前内联汇编语句的输出

  • BL是arm汇编中用来调用子程序的指令,要返回地址,它把BL后面一条指令的地址放到R14寄存器里,R15寄存器(PC当前指针地址)就设置成要跳往的地址。这样在这个子程序返回时,再mov PC,R14就可以返回到BL后面的地址了。
  • B不一样,B是直接 mov PC, 目标地址;用于不返回的跳转,不保存其后的地址到R14。

  • 查询u-boot.map得到需要调用的函数的地址

sudo vim u-boot.map

这里写图片描述
- 实例代码:

void (*my_print)(const char *fmt,...);//函数指针
int _start(void)
{
    int a,b,c,d;
    my_print=(void *)0x33f963a8;//u-boot中printf函数的地址

    my_print("1.in %s:before bl\n",__func__);
    //__volatile__:防止编译器优化
    __asm__ __volatile__(//汇编语句块
            "bl target\n"
            "bl my_func\n"
            "target:\n"
            );
    my_print("3,in %s:after bl\n",__func__);
    return 0;
}
void my_func(void)
{
    my_print("2,in %s\n",__func__);//__func__:打印当前函数名
}

你可能感兴趣的:(编程语言)