在ARM开发板上搭建 C语言 环境

栈初始化

相关概念

是一种具有后进先出性质的数据组织方式,也就是说后存放的先取出,先存放的后取出。栈底是第一个进栈的数据所处的位置,栈顶是最后一个进栈的数据所处的位置。

这里写图片描述

根据SP指针指向的位置,栈可以分为满栈和空栈。
1、满栈:当堆栈指针SP总是指向最后压入堆栈的数据。
2、空栈:当堆栈指针SP总是指向下一个将要放入数据的空位置。
ARM采用满栈。

这里写图片描述

根据SP指针移动的方向,栈可以分为升栈和降栈。
1、升栈:随着数据的入栈,SP指针从低地址->高地址移动。
2、降栈:随着数据的入栈,SP指针从高地址->低地址移动。
ARM采用降栈。

这里写图片描述

ARM采用满降栈。

简单的讲,栈帧(stack frame)就是一个函数所使用的那部分栈,所有函数的栈帧串起来就组成了一个完整的栈。栈帧的两个边界分别由fp(r11)sp(r13)来限定。

栈的作用:
1、保存局部变量
2、传递参数
3、保存寄存器值

初始化栈空间:

init_stack:
    ldr sp, =0x54000000  @4是任意指定的,指向内存64M的位置
    mov pc ,lr

BSS段初始化

BSS段的作用:
存放未初始化的全局变量。

BSS段初始化代码: 清空BSS段

clean_bss:                 @清空未初始化数据段 BSS段    
    ldr r1, =bss_start     @在lds文件中定义的变量
    ldr r2, =bss_end
    cmp r1, r2
    moveq pc, lr

clean_loop:
    mov r0, #0
    str r0, [r1], #4
    cmp r1, r2
    bne clean_loop
    mov pc, lr

指令B和BL为相对跳转,直接给pc指针赋值就是绝对跳转,跳转到C语言代码需要使用绝对跳转,使用ldr指令给pc指针复制。

采用C语言编程序:
在完成了栈和bss段的初始化之后,可以使用c语言

    bl init_stack
    bl clean_bss
    ldr pc, =gboot_main     
    @bl light_LED

C语言如下:

#define GPMCON (volatile unsigned long *)0x7F008820
#define GPMDAT (volatile unsigned long *)0x7F008824

void gboot_main()
{
    *(GPMCON) = 0x1111;
    *(GPMDAT) = 0b0101;
}

C与汇编混合编程

C语言与汇编语言的特点:
汇编语言:执行效率高;编写繁琐
C语言:可读性强,移植性好,调试方便

在对执行效率要求比较高,或者能够更直接地控制处理器(例如cpsr寄存器)的情况下,可以采用C和汇编混合编程。

汇编调用C函数
在上一部分的gboot_main()函数就是汇编对C函数的调用,直接使用ldr指令,给PC赋值,把函数名赋值给PC指针即可。

C调用汇编函数
直接用标号作为函数名,参数为空,以上面的代码为例,可以在c文件中调用汇编函数,如:

.global light_LED

void gboot_main()
{
    light_LED();
}

但是,一定要注意:必须把汇编函数的标号先声明为全局的,否则C文件找不到汇编文件中的汇编函数标号。

C内嵌汇编

格式:

两个下划线+asm+两个下划线
这里写图片描述

1、汇编语句部分:汇编语句的集合,可以包含多条汇编语句,每条语句之间需要使用换行符 “\n”隔开或使用分号“ ; ”隔开,内容都要用引号套上。
2、输出部分:在汇编中被修改的C变量列表。
3、输入部分: 作为参数输入到汇编中的变量列表。
4、破坏描述部分: 执行汇编指令会破坏的寄存器描述。

在C语言的asm块中,需要使用//来表示注释。

举例1,向cpsr寄存器写入内容:

这里写图片描述

%0表示第0号参数,凡是要读的参数都要写入输入部分,”r”表示输入的性质是一个通用寄存器的值,具体是那个通用寄存器由系统自己选择,value是输入的变量的值。

举例2,从cpsr寄存器中读取内容

这里写图片描述
赋值给value。

举例3,使用volatile来阻止优化
这里写图片描述
使用volatile来告诉编译器,不要对接下来的这部分代码进行优化。

举例4,使用asm来内嵌点亮LED程序

    __asm__(
        "ldr r1, =0x7F008820\n"   
        "ldr r0, =0x1111\n"
        "str r0, [r1]\n"

        "ldr r1, =0x7F008824 \n"    
        "mov r0, #0b0101\n"
        "str r0, [r1]\n"
        :
        :
        : "memory"
    );
  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值