一. 设置栈

  1.1. C语言运行时需要和栈的意义

    1.1.1. “C语言运行时(runtime)”需要一定的条件,这些条件由汇编来提供。C语言运行时主要是需要栈

    1.1.2. C语言与栈的关系

      a. C语言中的局部变量都是用栈来实现的。如果我们汇编部分没有给C部分预先设置合理合法的栈地址,那么C代码中定义的局部变量就会落空,整个程序就死掉了。

      b. 我们平时在编写单片机程序(譬如51单片机)或者编写应用程序时并没有去设置栈,但是C程序还是可以运行的。原因是:在单片机中由硬件初始化时提供了一个默认可用的栈,在应用程序中我们编写的C程序其实并不是全部,编译器(gcc)在链接的时候会帮我们自动添加一个头,这个头就是一段引导我们的C程序能够执行的一段汇编实现的代码,这个代码中就帮我们的C程序设置了栈及其他的运行时需要。

    1.1.3. CPU模式和各种模式下的栈

      1.1.3. 在ARM中37个寄存器中,每种模式下都有自己的独立的SP寄存器(r13),为什么这么设计?

        a. 如果各种模式都使用同一个SP,那么就意味着整个程序(操作系统内核程序、用户自己编写的应用程序)都是用一个栈的。你的应用程序如果一旦出错(譬如栈溢出),就会连累操作系统的栈也损坏,整个操作系统的程序就会崩溃。这样的操作系统设计是非常脆弱的,不合理的。

        b. 解决方案就是各种模式下用不同的栈。我的操作系统内核使用自己的栈,每个应用程序也使用自己独立的栈,这样各是各的,一个损坏不会连累其他人。

        PS: S5PV210系统在复位后默认是进入SVC模式的,裸机程序运行在此模式

  1.2. 汇编程序设置栈

    a. 栈必须是当前一段可用的内存(可用的意思是这个地方必须有被初始化过可以访问的内存,而且这个内存只会被我们用作栈,不会被其他程序征用)

    b. 当前CPU刚复位(刚启动),外部的DRRAM尚未初始化,目前可用的内存只有内部的SRAM(因为它不需初始化即可使用)。因此我们只能在SRAM中找一段内存来作为SVC的栈。

    c. 栈有四种:满减栈 满增栈 空减栈 空增栈,详情查看《ARM汇编3

    d. 查阅《iROM_application_note》中的memory map,可知SVC栈应该设置为0xd0037D80

#define SVC_STACK 0xd0037d80
ldr sp, = SVC_STACK @set stack

二. 使用c编程

  2.1. 汇编启动代码

    a. 设置栈地址

    b. 调用C函数led_blink

/*
* file name :set_stack.S
* author: MUSK
* description:set stack,
*/
#define WATCHCON 0xE2700000
#define SVC_STACK 0xd0037d80
.global _start
_start:
ldr r1, =WATCHCON @Watchdog Timer Control Register address
ldr r0, [r1] @config corresponding register
and r0, r0,#(~(0x01<<)) @config corresponding register
str r0, [r1] ldr sp, = SVC_STACK @set stack bl led_blink b . @while()

  2.2. 编写C文件

    a. 该文件主要实现LED的闪烁

#define GPJ0CON  ((volatile unsigned int *)0xE0200240)
#define GPJ0DAT ((volatile unsigned int *)0xE0200244)
void delay(void);
void led_blink(void)
{
//led初始化, *GPJ0CON &=0xff000fff;
*GPJ0CON |=0x00111000;
while()
{
*GPJ0DAT &=~((0x01<<)|(0x01<<)|(0x01<<));
delay();
*GPJ0DAT |=((0x01<<)|(0x01<<)|(0x01<<));
delay();
}
} void delay(void)
{
volatile unsigned int times =;
while(times--); }

三. 编译测试

  3.1. 编译前Makefile文件

set_stack.bin: set_stack.o led.o
arm-linux-ld -Ttext 0x0 -o set_stack.elf $^
arm-linux-objcopy -O binary set_stack.elf set_stack.bin
arm-linux-objdump -D set_stack.elf > set_stack_elf.dis
gcc mkv210_image.c -o mkx210
./mkx210 set_stack.bin .bin %.o : %.S
arm-linux-gcc -o $@ $< -c %.o : %.c
arm-linux-gcc -o $@ $< -c clean:
rm *.o *.elf *.bin *.dis mkx210 -f

  3.2. 编译结果

    a. 编译报错:led.o:(.ARM.exidx+0x0): undefined reference to `__aeabi_unwind_cpp_pr1'

    b. google问题后解决方法是编译命令后加上-nostdlib

root@ubuntu:/mnt/hgfs/windows_share/baseC/lesson1.5.3-set-stack2# ls
led.c Makefile mkv210_image.c set_stack.S write2sd 说明.txt
root@ubuntu:/mnt/hgfs/windows_share/baseC/lesson1.5.3-set-stack2#
root@ubuntu:/mnt/hgfs/windows_share/baseC/lesson1.5.3-set-stack2#
root@ubuntu:/mnt/hgfs/windows_share/baseC/lesson1.5.3-set-stack2# make
arm-linux-gcc -o set_stack.o set_stack.S -c #-nostdlib
arm-linux-gcc -o led.o led.c -c #-nostdlib
arm-linux-ld -Ttext 0x0 -o set_stack.elf set_stack.o led.o
led.o:(.ARM.exidx+0x0): undefined reference to `__aeabi_unwind_cpp_pr1'
led.o:(.ARM.exidx+0x8): undefined reference to `__aeabi_unwind_cpp_pr0'
make: *** [set_stack.bin] Error
root@ubuntu:/mnt/hgfs/windows_share/baseC/lesson1.5.3-set-stack2#

  3.3. 修改后的Makefile文件

    a. 增加-nostdlib

set_stack.bin: set_stack.o led.o
arm-linux-ld -Ttext 0x0 -o set_stack.elf $^
arm-linux-objcopy -O binary set_stack.elf set_stack.bin
arm-linux-objdump -D set_stack.elf > set_stack_elf.dis
gcc mkv210_image.c -o mkx210
./mkx210 set_stack.bin .bin %.o : %.S
arm-linux-gcc -o $@ $< -c -nostdlib %.o : %.c
arm-linux-gcc -o $@ $< -c -nostdlib clean:
rm *.o *.elf *.bin *.dis mkx210 -f

    b. 重新make

root@ubuntu:/mnt/hgfs/windows_share/baseC/lesson1.5.3-set-stack2# make clean
rm *.o *.elf *.bin *.dis mkx210 -f
root@ubuntu:/mnt/hgfs/windows_share/baseC/lesson1.5.3-set-stack2# make
arm-linux-gcc -o set_stack.o set_stack.S -c -nostdlib
arm-linux-gcc -o led.o led.c -c -nostdlib
arm-linux-ld -Ttext 0x0 -o set_stack.elf set_stack.o led.o
arm-linux-objcopy -O binary set_stack.elf set_stack.bin
arm-linux-objdump -D set_stack.elf > set_stack_elf.dis
gcc mkv210_image.c -o mkx210
./mkx210 set_stack.bin .bin
root@ubuntu:/mnt/hgfs/windows_share/baseC/lesson1.5.3-set-stack2#

参考《朱老师.1.2ARM裸机课件》

从汇编到C的更多相关文章

  1. u-boot源码汇编段简要分析

    Hi,大家好!我是CrazyCatJack,你们可以叫我CCJ或者疯猫.今天我给大家带来的是u-boot的源代码汇编段分析,以后还会给大家讲解后续的C代码,请持续关注哦^_^ 先简单说一下u-boot ...

  2. GCC 预处理、编译、汇编、链接..

    1简介 GCC 的意思也只是 GNU C Compiler 而已.经过了这么多年的发展,GCC 已经不仅仅能支持 C 语言:它现在还支持 Ada 语言.C++ 语言.Java 语言.Objective ...

  3. GDB调试汇编堆栈过程分析

    GDB调试汇编堆栈过程分析 分析过程 这是我的C源文件:click here 使用gcc - g example.c -o example -m32指令在64位的机器上产生32位汇编,然后使用gdb ...

  4. Beennan的内嵌汇编指导(译)Brennan's Guide to Inline Assembly

    注:写在前面,这是一篇翻译文章,本人的英文水平很有限,但内嵌汇编是学习操作系统不可少的知识,本人也常去查看这方面的内容,本文是在做mit的jos实验中的一篇关于内嵌汇编的介绍.关于常用的内嵌汇编(AT ...

  5. 从linux0.11中起动部分代码看汇编调用c语言函数

    上一篇分析了c语言的函数调用栈情况,知道了c语言的函数调用机制后,我们来看一下,linux0.11中起动部分的代码是如何从汇编跳入c语言函数的.在LINUX 0.11中的head.s文件中会看到如下一 ...

  6. C内嵌汇编-格式

    C内嵌汇编-格式: __asm__(汇编语句部分:输出部分:输入部分破坏描述部分);C内嵌汇编以关键字"__asm__"或"asm"开始, 下辖四个部分, 各部 ...

  7. 20145212——GDB调试汇编堆栈过程分析

    GDB调试汇编堆栈过程分析 测试代码 #include <stdio.h> short val = 1; int vv = 2; int g(int xxx) { return xxx + ...

  8. C程序汇编运行模式简析

    SJTUBEAR 原创作品转载请注明出处 /<Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 1. 汇编 ...

  9. 生成ARM汇编

    使用ndk即可生成arm汇编 1.首先写好hello.c 2.编写makefile #ndk根目录 NDK_ROOT=E:\Android\android-ndk-r10b #编译器根目录 TOOLC ...

  10. gdb调试汇编堆栈过程的学习

    gdb调试汇编堆栈过程的学习 以下为C源文件 使用gcc - g code.c -o code -m32指令在64位的机器上产生32位汇编,然后使用gdb example指令进入gdb调试器: 进入之 ...

随机推荐

  1. 对MySQL binlog日志解析,统计每张表的DML次数

    想要获取每天数据库每张表的DML的次数,统计热度表,可以使用该脚本 # coding:utf-8 # 解析binlog,统计热度表,表的DML个数 import sys import os # mys ...

  2. Codeforces 963A Alternating Sum ( 思维 && 数论 )

    题意 : 题目链接 分析 : Tutorial 讲的很清楚 至于为什么这样去考虑 算是一个经验问题吧 如果一个问题要你给出模意义下的答案 就多考虑一下答案是要用逆元构造出来 也就说明有除法的存在 那么 ...

  3. pycharm如何添加固定代码块

    1. file -- settings -- 搜索框输入live,找到 Live Templates 2. 选择你要添加到哪个语言中去,打开python组,并点击右上角 “+”,选择 1.Live T ...

  4. sh_05_非公勿入

    sh_05_非公勿入 # 练习3: 定义一个布尔型变量 is_employee,编写代码判断是否是本公司员工 is_employee = False # 如果不是提示不允许入内 # 在开发中,通常希望 ...

  5. http response压缩

    http response压缩 一.Spring boot启用Gzip压缩 application.xml新增配置: 未启用压缩时试验接口传输大小不变为61.88M,耗时1分多钟 启动压缩时试验接口传 ...

  6. Android学习笔记之数据的Sdcard存储方法及操作sdcard的工具类

    FileService.java也就是操作sdcard的工具类: ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 ...

  7. THU-CCF WC2019两开花记

    今年年初,清华大学举办的THUWC2019即将正式开启,我将继续扮演蒟蒻OIER,努力创造一个菜鸡的形象,THU-CCF WC两爆炸,笑掉各位大牙,大家多多关注. Day0 广州好热啊╰(‵□′)╯! ...

  8. [CSP-S模拟测试]:stone(结论+桶+前缀和+差分)

    题目描述 $Cab$有两行石子,每个石子上有一个字母,为$'C''A''B'$中的一个.一开始,在每行第一个石子上站着一只$lucky$,$Cab$每次可以选择一个字母,使得所站石子上字母为该字母的$ ...

  9. ros the public key is not available

    W: An error occurred during the signature verification. The repository is not updated and the previo ...

  10. Mybaits基本的CURD操作

    1 首先在Mapper.xml配置 <!-- parameterType:参数类型,可以省略, 获取自增主键的值: mysql支持自增主键,自增主键值的获取,mybatis也是利用stateme ...