C语言初始化——bss段初始化、跃入C、C与汇编

1.bss段初始化

变量 存放位置
初始化的全局变量 数据段
局部变量
malloc函数分配的
未初始的全局变量 bss段

说明:全局变量在未赋初值时,会被保留到bss段。

测试:

 #include <stdio.h>
   
  int bss_test;                                                               
  
  int main()
  {
    bss_test=100;
   return 0;
  }
bss.c

arm-linux-gcc bss.c -o bss

arm-linux-readelf -a bss >bssdump

vim bssdump(看全局变量的地址是否在bss段的起始于结束地址之间)

编写程序清零bss段

 1 clear_bss:
 2     ldr r0,=bss_start
 3     ldr r1,=bss_end
 4     cmp r0,r1
 5     moveq pc,lr
 6 
 7 clean_loop:
 8     mov r2,#0
 9     str r2,[r0],#4
10     cmp r0,r1
11     bne clean_loop
12     mov pc,lr
clear_bss

2.跃入C

点亮led的C程序

 1 #define GPKCON (volatile unsigned long*)0x7f008800
 2 #define GPKDAT (volatile unsigned long*)0x7f008808
 3 
 4 int gboot_main()
 5 {
 6     *(GPKCON) = 0x11110000;
 7     *(GPKDAT) = 0xa0;
 8     
 9     return 0;    
10 }
gboot_main

3.C与汇编混合编程

3.1 汇编调用C函数

把函数名赋予PC指针ldr pc,=gboot_main

3.2 C函数调用汇编

在前面点亮led中light_led函数声明为全局的(汇编中被其他程序引用)

#define GPKCON 0x7f008800
#define GPKDAT 0x7f008808        
.global light_led                                  
light_led:
ldr r0, =GPKCON
ldr r1, =0x11110000
str r1, [r0]

ldr r0, =GPKDAT
ldr r1, =0xa0
str r1, [r0]
mov pc, lr
light_led

3.3 C中内嵌汇编

3.3.1 格式

__asm__(
汇编语句部分
:输出部分
:输入部分
:破坏描述部分
);
注:C内嵌汇编以关键字”__asm__”或”asm”开始,下辖四个部分,各部分之间使用":"分开, 第一部分是必须写的,后面三部分是可以省略,但是分号:不能省略

汇编语句部分:汇编语句的集合,可以包含多条汇编语句,每条语句之间需要使用换行符 “ ”隔开或使用分号“ ; ”隔开

输出部分:在汇编中被修改的C变量列表

输入部分: 作为参数输入到汇编中的变量列表

破坏描述部分: 执行汇编指令会破坏的寄存器描述

3.3.2 范例

向cp15 c1寄存器写入数值

void write_p15_c1 (unsigned long value)
{
__asm__(
“mcr p15, 0, %0, c1, c0, 0
”
:
: “r” (value)             @编译器选择一个R*寄存器(通用寄存器)
: "memory");
}

向cp15 c1寄存器读出数值

unsigned long read_p15_c1 (void)
{
unsigned long value;
__asm__(
“mrc p15, 0, %0, c1, c0, 0
”
: “=r” (value)           @ ’=‘ 表示只写操作数,用于输出部分
:
: "memory");
return value;
}

3.3.3 优化

unsigned long old;
unsigned long temp;
__asm__ volatile(
"mrs %0, cpsr 
"

"orr %1, %0, #128 
“
"msr cpsr_c, %1
"
: "=r“ (old), "=r“ (temp)
: :
"memory");
}

使用volatile来告诉编译器,不要对接下来的这部分代码优化

测试

 1 #define GPKCON 0x7f008800
 2 #define GPKDAT 0x7f008808 
 3 int gboot_main()
 4 {
 5     //*(GPKCON) = 0X11110000;
 6     //*(GPKDAT) = 0xa0;
 7     __asm__(
 8            "ldr r1, =0x11110000
"
 9            "str r1, [%0]
"
10          
11            "ldr r1, =0xa0
"
12            "str r1, [%1]
"
13              :
14              :"r"(GPKCON),"r"(GPKDAT)
15              :"r1"
16             );
17     return 0;
18 }
原文地址:https://www.cnblogs.com/boyiliushui/p/5906844.html