繁体中文
高级搜索
 
首页 | 电子技术应用 | 行业最新动态 | 行业最新产品 | 软件资料下载 | 电路图纸欣赏 | 博客文章精选 | 电子精品论坛 | 电子技术贴吧

当前位置:首页 >> 博客文章精选 >> 嵌入式系统-博客 >> WINARM中的CRT0.S代码分析
WINARM中的CRT0.S代码分析
作者:   来源: 发表时间:2007-02-07  字号:  

CRT0.S代码分析

jupiter 2006.08.20

.global main // int main(void)

.global _etext // -> .data initial values in ROM

.global _data // -> .data area in RAM

.global _edata // end of .data area

.global __bss_start // -> .bss area in RAM

.global __bss_end__ // end of .bss area

.global _stack // top of stack

.global symbol

GNU AS.global使ld能够看见这个符号。如果你在程序的某个部分中定义了symbol,那么在与它一起链接的其它程序中,这个符号也是可见的。

在这部分中定义了几个符号,其中包括main,这是我们所写的C程序的入口;_etext,即end of texttext段的末尾也就是data段的开始,从此处开始是.data段,.data段存放的是需要被初始化的数据,例如那些带有初始化值的全局变量;_data_edata指明了数据段的起始和结束位置;同理__bss_start__bss_end__指明了bss段的起始和结束位置;_stack指明了栈顶,对于ARM处理器来说,栈一般是满递减的,即full descending

/************

在这里我简单的介绍一下程序的装载与执行过程。程序一般可以分成textdatabss段,我们必须把程序放在非易失性存储器(NVM)中,试着想一下,如果你把程序放在RAM中,那么系统掉电之后,你还能运行你的程序吗?而每个段又有自己的装载地址和运行地址,装载地址和运行地址可能相同,也可能不同。但是对于data段来说,这两个地址肯定是不相同的,因为我们一般不能在程序运行的过程中修改NVM的内容,我们需要在程序的初始化代码中将data段的内容从它的装载地址拷贝到它的运行地址处(我们稍后就能看到这是如何做到的)。回到上面的问题,_etext就是data段在NVM中的起始地址,而_data就是data段运行时的起始地址。这里有一个常识,在可执行文件中,一般首先存放text段,紧接着是data段,最后才是bss段,当然对于bss段来说还有一个技巧以后再谈。

************/

//定义各个异常模式的堆栈大小

.set UND_STACK_SIZE, 0x00000004

.set ABT_STACK_SIZE, 0x00000004

.set FIQ_STACK_SIZE, 0x00000004

.set IRQ_STACK_SIZE, 0X00000080

.set SVC_STACK_SIZE, 0x00000004

//定义标准模式位和PSR中的中断(I & F)标志

.set MODE_USR, 0x10 // User Mode

.set MODE_FIQ, 0x11 // FIQ Mode

.set MODE_IRQ, 0x12 // IRQ Mode

.set MODE_SVC, 0x13 // Supervisor Mode

.set MODE_ABT, 0x17 // Abort Mode

.set MODE_UND, 0x1B // Undefined Mode

.set MODE_SYS, 0x1F // System Mode

.set symbol, expression

设置symbol的值为expression。这会改变symbol的值和类型以与expression保持一致。如果symbol具有external标志,那么此标志保持不变。可以在汇编语句中多次.set一个符号。如果你.set一个全局符号,那么保存在目标文件中的将是最后一次设置的值。

.equ I_BIT, 0x80 // when I bit is set, IRQ is disabled

.equ F_BIT, 0x40 // when F bit is set, FIQ is disabled

.equ symbol, expression

.equ的用法和作用与.set相同。

.text

.code 32

.align 2

.global _boot

.func _boot

_boot:

// Runtime Interrupt Vectors

// -------------------------

Vectors:

b _start // reset - _start

ldr pc,_undf // undefined - _undf

ldr pc,_swi // SWI - _swi

ldr pc,_pabt // program abort - _pabt

ldr pc,_dabt // data abort - _dabt

nop // reserved

ldr pc,[pc,#-0xFF0] // IRQ - read the VIC

ldr pc,_fiq // FIQ - _fiq

#if 0

// Use this group for production

_undf: .word _reset // undefined - _reset

_swi: .word _reset // SWI - _reset

_pabt: .word _reset // program abort - _reset

_dabt: .word _reset // data abort - _reset

_irq: .word _reset // IRQ - _reset

_fiq: .word _reset // FIQ - _reset

#else

// Use this group for development

_undf: .word __undf // undefined

_swi: .word __swi // SWI

_pabt: .word __pabt // program abort

_dabt: .word __dabt // data abort

_irq: .word __irq // IRQ

_fiq: .word __fiq // FIQ

__undf: b . // undefined

__swi: b . // SWI

__pabt: b . // program abort

__dabt: b . // data abort

__irq: b . // IRQ

__fiq: b . // FIQ

#endif

.size _boot, . - _boot

.endfunc

这个部分定义了异常向量表。

.func name [,label]

.func为函数name添加调试信息,但是除非在汇编的时候使能调试信息否则这些信息被忽略。目前仅支持—gstabs选项。Label是函数的入口点,如果省略,那么必须给name添加一个前缀字符,这个字符通常是一个下划线(_)或者为空,这依赖于目标平台。目前所有的函数的返回类型都被定义为void。函数必须以.endfunc结束。

编译器生成.size这个命令符是为了在符号表中包含辅助调试信息。它仅在.def/.endef对中才是允许的。.size仅仅在生成COFF格式时才有意义;当as生成b.out时,虽然它可以接收这个命令符,但只是忽略它。(这里我们可以认为它不存在)

// Setup the operating mode & stack.

// ---------------------------------

.global _start, start, _mainCRTStartup

.func _start

_start:

start:

_mainCRTStartup:

// Initialize Interrupt System

// - Set stack location for each mode

// - Leave in System Mode with Interrupts Disabled

// -----------------------------------------------

ldr r0,=_stack

msr CPSR_c,#MODE_UND|I_BIT|F_BIT // Undefined Instruction Mode

mov sp,r0

sub r0,r0,#UND_STACK_SIZE

msr CPSR_c,#MODE_ABT|I_BIT|F_BIT // Abort Mode

mov sp,r0

sub r0,r0,#ABT_STACK_SIZE

msr CPSR_c,#MODE_FIQ|I_BIT|F_BIT // FIQ Mode

mov sp,r0

sub r0,r0,#FIQ_STACK_SIZE

msr CPSR_c,#MODE_IRQ|I_BIT|F_BIT // IRQ Mode

mov sp,r0

sub r0,r0,#IRQ_STACK_SIZE

msr CPSR_c,#MODE_SVC|I_BIT|F_BIT // Supervisor Mode

mov sp,r0

sub r0,r0,#SVC_STACK_SIZE

msr CPSR_c,#MODE_SYS|I_BIT|F_BIT // System Mode

mov sp,r0

这一步主要是设置各个异常模式的堆栈,注意在设置的时候需要禁止IRQFIQ。这段代码也是系统复位后执行的第一段代码。执行完这段代码后系统处于系统模式,并且IRQFIQ都是禁止的。

// Copy initialized data to its execution address in RAM

// -----------------------------------------------------

#ifdef ROM_RUN

ldr r1,=_etext // -> ROM data start

ldr r2,=_data // -> data start

ldr r3,=_edata // -> end of data

1: cmp r2,r3 // check if data to move

ldrlo r0,[r1],#4 // copy it

strlo r0,[r2],#4

blo 1b // loop until done

#endif

// Clear .bss

// ----------

mov r0,#0 // get a zero

ldr r1,=__bss_start // -> bss start

ldr r2,=__bss_end__ // -> bss end

2: cmp r1,r2 // check if data to clear

strlo r0,[r1],#4 // clear 4 bytes

blo 2b // loop until done

这两段代码主要完成data段的搬运和bss段的清零。

// Call main program: main(0)

// --------------------------

mov r0,#0 // no arguments (argc = 0)

mov r1,r0

mov r2,r0

mov fp,r0 // null frame pointer

mov r7,r0 // null frame pointer for thumb

ldr r10,=main

mov lr,pc

bx r10 // enter main()

.size _start, . - _start

.endfunc

这段代码完成到C语言main函数的跳转。

.global _reset, reset, exit, abort

.func _reset

_reset:

reset:

exit:

abort:

#if 0

// Disable interrupts, then force a hardware reset by driving P23 low

// -------------------------------------------------------------------

mrs r0,cpsr // get PSR

orr r0,r0,#I_BIT|F_BIT // disable IRQ and FIQ

msr cpsr,r0 // set up status register

ldr r1,=(PS_BASE) // PS Base Address

ldr r0,=(PS_PIO) // PIO Module

str r0,[r1,#PS_PCER_OFF] // enable its clock

ldr r1,=(PIO_BASE) // PIO Base Address

ldr r0,=(1<<23) // P23

str r0,[r1,#PIO_PER_OFF] // make sure pin is contolled by PIO

str r0,[r1,#PIO_CODR_OFF] // set the pin low

str r0,[r1,#PIO_OER_OFF] // make it an output

#endif

b . // loop until reset

.size _reset, . - _reset

.endfunc

.end


!注意:如果您发现此文章出现影响您的阅读的状况,请从浏览器地址栏里复制本文的链接到留言本报告给站长解决!
  • 上一篇: WINARM中的CRT0.S代码分析
  • 下一篇: IBM采用自成形材料绝缘 芯片提速三分之一

  • >> 联系我们请给我们留言·留言本
    本站所有提供的信息软件资料均来自网络,版权及著作权归原作者所有,如果无意中侵犯了您的相关权利或触及法律法规,请给我们留言, 我们将在24小时内删除。
      浙ICP备05071687号  电子技术精品网