`
jsntghf
  • 浏览: 2476317 次
  • 性别: Icon_minigender_1
  • 来自: 苏州
社区版块
存档分类
最新评论

汇编写启动代码之设置栈和调用C语言

阅读更多

本文使用的开发板是九鼎创展的X210 iNand版本。

 

一、预备知识

 

1、C语言运行时和栈

(1)C语言运行时需要

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

 

(2)C语言与栈的关系

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

 

2、CPU模式和各种模式下的栈

(1)在ARM的37个寄存器中,每种模式下都有自己的独立的SP寄存器(r13)。

(2)我们要设置栈,不可能而且也没有必要去设置所有的栈。我们先要找到当前的模式,然后设置该模式下的栈到合理合法的位置即可。

(3)系统在复位后默认是进入SVC模式。

(4)我们先把模式设置为SVC,再直接操作SP,即可访问SVC模式下的SP。因为复位后就已经是SVC模式了,所以直接设置SP即可。

 

3、设置栈指针

(1)栈必须是当前一段可用的内存,这个内存必须是被初始化过可以访问的内存,而且这个内存只会被用作栈,不会被其他程序占用。

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

(3)在ARM中,ATPCS要求使用满减栈

 

二、查阅iROM Application Note文档

 

 

由上图可知SVC栈应该设置为0xD0037D80。

 

三、代码实现

 

#define SVC_STACK 0xD0037D80

.global _start					
_start:
	ldr sp, =SVC_STACK
	
    b .

 

四、汇编调用C函数,实现LED闪烁效果

 

(1)led.c

#define GPJ0CON	 0xE0200240
#define GPJ0DAT	 0xE0200244

#define rGPJ0CON *((volatile unsigned int *)GPJ0CON)
#define rGPJ0DAT *((volatile unsigned int *)GPJ0DAT)

void delay(void);

void led_blink(void) {
	rGPJ0CON = 0x11111111;
	
	while(1) {
		// led亮
		rGPJ0DAT = ((0<<3) | (0<<4) | (0<<5));
		// 延时
		delay();
		// led灭
		rGPJ0DAT = ((1<<3) | (1<<4) | (1<<5));
		// 延时
		delay();
	}
}

void delay(void) {
	volatile unsigned int i = 900000;		
	while (i--);							
}

 

(2)Makefile

led.bin: start.o led.o
	arm-linux-ld -Ttext 0x0 -o led.elf $^
	arm-linux-objcopy -O binary led.elf led.bin
	arm-linux-objdump -D led.elf > led_elf.dis
	gcc mkv210_image.c -o mkx210
	./mkx210 led.bin 210.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

 

(3)start.S

#define SVC_STACK	0xD0037D80

.global _start					
_start:
	ldr sp, =SVC_STACK

	bl led_blink					
	
	b .

 

分享到:
评论

相关推荐

    汇编程序与代码块装载

    至于操作系统的大量代码,一般用C语言和汇编语言混合编写,保存为磁盘文件后,再由启动程序装载入内存。 DOS和Windows的COM可执行文件简单小巧,可用于引导代码的运行测试。 为了调试我们编写的汇编语言程序,可以...

    linux汇编-AT&T的386汇编语言

    在阅读Linux源代码时,你可能碰到一些汇编语言片段,有些汇编语言出现在以.S 为扩展名的汇编文件中,在这种文件中,整个程序全部由汇编语言组成。有些汇编命令出 现在以.c为扩展名的C文件中,在这种文件中,既有...

    ARM的启动代码为什么要用汇编语言

    在ARM中讲到ARM的启动代码必须有汇编语言写成,一直不是很了解。  书上给的原因是C语言不具备上电立即运行的条件:  全局变量没有初始化、系统堆栈没有初始化等。  那单片机的C语言怎么就不要启动代码?(keil带...

    嵌入式系统/ARM技术中的ARM的启动代码为什么要用汇编语言

    在ARM中讲到ARM的启动代码必须有汇编语言写成,一直不是很了解。  书上给的原因是C语言不具备上电立即运行的条件:  全局变量没有初始化、系统堆栈没有初始化等。  那单片机的C语言怎么就不要启动代码?(keil带...

    u-boot移植实验

    2 阶段2是C语言代码,在lib_arm/board.c中的start_armboot是C语言开始的函数,也是整个启动代码中C语言的主函数。这个函数调用一系列的初始化函数,然后进入主UBOOT命令行,进入命令循环(即整个boot的工作循环),...

    C语言讲解 主讲:邓君峰

    C语言特点 语言特点 C程序结构 程序结构 基本的输入输出 程序设计语言的发展机器语言 汇编语言 高级语言 – 通用语言 fortran, basic C VB SQL Delphi Powerbuild C++ ( VC++ BC++ ) – 数据库语言 foxbase ,FoxPro ...

    华为鲲鹏云HCIA考试资料(二)

    29.性能优化工具特性 支持采集整个系统或指定进程(包括运行中的进程或直接启动的进程)的CPU Cycles性能事件,能够快速定位到热点函数,...支持显示汇编代码的控制流图。 支持分析Java代码的热点函数及热点指令

    美国..现代编译原理C语言描述.高清版

    书中专门为学生提供了一个用C语言编写的实习项目,包括前端和后端设计,学生可以在一学期内创建一个功能完整的编译器。  本书适用于高等院校计算机及相关专业的本科生或研究生,也可供科研人员或工程技术人员参考。...

    嵌入式Linux C编程入门(第2版) PPT

    7.2.2 堆和栈的区别 215 7.3 嵌入式linux可移植性考虑 216 7.3.1 字长和数据类型 216 7.3.2 数据对齐 218 7.3.3 字节顺序 218 7.4 c和汇编的接口 219 7.4.1 内嵌汇编的语法 219 7.4.2 编译器...

    自己动手写操作系统 pdf

    自己动手写操作系统在详细分析操作系统原理的基础上,用丰富的实例代码,一步一步地指导读者用C语言和汇编语言编写出一个具备操作系统基本功能的操作系统框架。本书不同于其他的理论型书籍,而是提供给读者一个动手...

    Turbo C2.0

     同模式启动代码C?.LIB  不同模式运行库GRAPHICS.LIB  图形库EMU.LIB  8087仿真库FP87.LIB 8087库  *.H Turbo C头文件  *.BGI 不同显示器图形驱动程序  *.C Turbo C例行程序(源文件)  其中:上面的?分别为...

    自己动手写操作系统

    本书在详细分析操作系统原理的基础上,用丰富的实例代码,一步一步地指导读者用C语言和汇编语言编写出一个具备操作系统基本功能的操作系统框架。本书不同于其他的理论型书籍,而是提供给读者一个动手实践的路线图。...

    自己动手写操作系统(含源代码).part2

    如果考虑到操作系统作为软硬件桥梁的特殊地位,那么它可能看上去比一般的软件系统更难理解,因为其核心部分往往包含许多直接针对CPU、内存和 I/O端口的操作,它们夹杂在一片代码汪洋之中,显得更加晦涩。 我们有许多...

    自己动手写操作系统(含源代码).part1

    如果考虑到操作系统作为软硬件桥梁的特殊地位,那么它可能看上去比一般的软件系统更难理解,因为其核心部分往往包含许多直接针对CPU、内存和 I/O端口的操作,它们夹杂在一片代码汪洋之中,显得更加晦涩。 我们有许多...

    Windows内核安全与驱动开发光盘源码

    12.7 读/写加密和解密 285 12.7.1 在读取时进行解密 285 12.7.2 分配与释放MDL 286 12.7.3 写请求加密 287 12.8 crypt_file的组装 289 12.8.1 crypt_file的初始化 289 12.8.2 crypt_file的IRP预处理 290 12.8...

    Windows内核安全驱动开发(随书光盘)

    12.7 读/写加密和解密 285 12.7.1 在读取时进行解密 285 12.7.2 分配与释放MDL 286 12.7.3 写请求加密 287 12.8 crypt_file的组装 289 12.8.1 crypt_file的初始化 289 12.8.2 crypt_file的IRP预处理 290 12.8...

    windows驱动开发技术详解-part2

     4.3.6 用Device Tree查看WDM设备对象栈  4.4 设备的层次结构  4.4.1 驱动程序的垂直层次结构  4.4.2 驱动程序的水平层次结构  4.4.3 驱动程序的复杂层次结构  4.5 实验  4.5.1 改写HelloDDK查看驱动...

    Windows驱动开发技术详解的光盘-part1

    笔者将带领读者编写代码、编译、安装和调试程序。  1.1 DDK的安装  1.2 第一个驱动程序HelloDDK的代码分析  1.2.1 HelloDDK的头文件  1.2.2 HelloDDK的入口函数  1.2.3 创建设备例程  1.2.4 卸载驱动例程...

    STM32单片机的入门教程总结

    基于Cortex-m3内核的ARM处理器的出现,在优秀的Kei开发工具的支持下,可以自动生成启动代码,省去了复杂的Bootloader的编写。Thumb-2指令集的使用,使得开发人员不用再考虑ARM状态与Thumb状态的切换,节省了执行时间...

    RadASM 中文汉化版

    “标准化”:把你选中的代码按选项中的设置进行整理,使代码具有更好的可读性;“显示选项”:显示设置选项。 声明: 1、此汉化软件是免费软件,请在转载时保留其内容的完整性! 2、此软件仅用于个人学习使用,...

Global site tag (gtag.js) - Google Analytics