• 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 }
  • 相关阅读:
    POJ-2112 Optimal Milking(floyd+最大流+二分)
    网络流之最大流与最小费用流入门&&模板
    0316 校赛训练赛3 解题报告
    string的子串截取
    hash题目大汇总
    Codeforces Round #235 (Div. 2)
    poj2002 -- 点的hash
    hlgHCPC2014校赛训练赛 1 BB.序列问题
    树状数组模板,RMQ模板
    从未放弃--2014.1.21
  • 原文地址:https://www.cnblogs.com/boyiliushui/p/5906844.html
Copyright © 2020-2023  润新知