Reguire8和Preserve8
C和汇编有8位对齐的要求,这两个伪指令可以满足此要求,存在REQUIRE8<——> PRESERVE8的对应关系,但不是说有一个REQUIRE8就要有一个 PRESERVE8,如果是一个c文件和一个汇编文件的调用,也就涉及一个PRESERVE8或者是一个REQUIRE8.
另外,REQUIRE8和PRESERVE8并不完成8 byte 对齐的操作,对齐由ALIGN完成。
将ADS的代码移植到KEIL MDK上需要做的修改:
当用户拥有ADS遗留工程的所有源代码时,使用MDK重新编译链接全部代码是最好的解决方法,MDK中的新版本编译工具会重新生成满足堆栈8BYTE对齐要求的目标文件,避免由于堆栈不对齐引起的链接错误.
从ADS到KEIL很重要的一个修改的地方就是这里的8BYTE对齐,想要编译通过,在startup.s里面我们必须加入PRESERVE8指令,使得寄存器8BYTE对齐.
代码:
CODE32
PRESERVE8;这个在KEIL里面是必须的,要求8BYTE对齐.在ADS的启动代码中就没有.
AREA vectors,CODE,READONLY
Mode_USREQU0x10用户模式
Mode_FIQEQU0x11快中断模式
Mode_IRQEQU0x12中断模式
Mode_SVCEQU0x13管理模式
Mode_ABTEQU0x17中止模式
Mode_UNDEQU0x1B未定义模式
Mode_SYSEQU0x1F系统模式
参数的由来:这里各个模式的参数是由寄存器CPSR的模式位设置M[4:0]得来的,比如这里的用户模式,CPSR的M[4:0]设置为10000就是0x10,同理其他.详见<
I_BitEQU0x80; when I bit is set, IRQ is disabled
F_BitEQU0x40; when F bit is set, FIQ is disabled
也和CPSR寄存器的设置有关,这里两位是禁止/开启快速中断和一般中断的设置.
UND_Stack_SizeEQU0x00000000
SVC_Stack_SizeEQU0x00000100
ABT_Stack_SizeEQU0x00000000
FIQ_Stack_SizeEQU0x00000000
IRQ_Stack_SizeEQU0x00000100
USR_Stack_SizeEQU0x00000200
设置堆栈大小
Stack_SizeEQU(UND_Stack_Size + SVC_Stack_Size + ABT_Stack_Size +
FIQ_Stack_Size + IRQ_Stack_Size + USR_Stack_Size)
AREASTACK, NOINIT, READWRITE, ALIGN=3
Stack_MemSPACEStack_Size
Stack_TopEQUStack_Mem + Stack_Size
堆栈大小的设置,各公司写的启动代码有所不同,但是不影响大局,可以借鉴一些你认为比较简单的启动代码,然后写自己的堆栈地址和大小设置程序.
Heap_SizeEQU0x00000000
AREAHEAP, NOINIT, READWRITE, ALIGN=3
Heap_MemSPACEHeap_Size
AREA Init,CODE,READONLY,ALIGN=3 //指定后面的指令为8位对齐(2的3次方)
align n
它的含义就是使得下面的代码按一定规则对齐,.align n 指令的对齐值有两种方案,n 或 2^n ,各种平台最初的汇编器一般都不是gas,采取方案1或2的都很多,gas的目标是取代原来的汇编器,必然要保持和原来汇编器的兼容,因此在gas中如何解释 .align指令会显得有些混乱,原因在于保持兼容。arm-linux是按照2^n的方案对齐的. ARM的.align 5就是2的5次方(32位)对齐,也就是4字节(32位)对齐.
ARM
下面的是ARM的代码,不是THUMB.
Reset
LDRPC, ResetAddr
LDRPC, UndefinedAddr
LDRPC, SWI_Addr
LDRPC, PrefetchAddr
LDRPC, DataAbortAddr
DCD0xb9205f80
LDRPC, [PC, #-0xff0]
LDRPC, FIQ_Addr
ResetAddrDCDResetInit
UndefinedAddrDCDUndefined
SWI_AddrDCDSoftwareInterrupt
PrefetchAddrDCDPrefetchAbort
DataAbortAddrDCDDataAbort
NouseDCD0
IRQ_AddrDCD0
FIQ_AddrDCDFIQ_Handler
;未定义指令
Undefined
BUndefined
;软中断
SoftwareInterrupt
BSoftwareInterrupt
;取指令中止
PrefetchAbort
BPrefetchAbort
;取数据中止
DataAbort
BDataAbort
;快速中断
FIQ_Handler
STMFDSP!, {R0-R3, LR}
BLFIQ_Exception
LDMFDSP!, {R0-R3, LR}
SUBSPC,LR,#4
MOVR0, LR
;Build the SVC stack
;设置管理模式堆栈
MSRCPSR_c, #0xd3
LDRSP, StackSvc
;Build the IRQ stack
;设置中断模式堆栈
MSRCPSR_c, #0xd2
LDRSP, StackIrq
;Build the FIQ stack
;设置快速中断模式堆栈
MSRCPSR_c, #0xd1
LDRSP, StackFiq
;Build the DATAABORT stack
;设置中止模式堆栈
MSRCPSR_c, #0xd7
LDRSP, StackAbt
;Build the UDF stack
;设置未定义模式堆栈
MSRCPSR_c, #0xdb
LDRSP, StackUnd
;Build the SYS stack
;设置系统模式堆栈
MSRCPSR_c, #0x5f;#0xdf
LDRSP, =StackUsr
MOVPC, R0
BLTargetResetIni;目标板基本初始化;跳转到c语言入口 Jump to the entry point of C program
B__main
周立功启动代码:
;/****************************************Copyright (c)**************************************************
;**Guangzou ZLG-MCU Development Co.,LTD.
;**graduate school
;**http://www.zlgmcu.com
;**
;**--------------File Info-------------------------------------------------------------------------------
;** File name:Startup.s
;** Last modified Date:2004-09-17
;** Last Version:1.0
;** Descriptions:The start up codes for LPC2100, including the initializing codes for the entry point of exceptions and the stacks of user tasks.
;**Every project should have a independent copy of this file for related modifications
;**------------------------------------------------------------------------------------------------------
;** Created by:Chenmingji
;** Created date:2004-02-02
;** Version:1.0
;** Descriptions:The original version//原著
;**
;**------------------------------------------------------------------------------------------------------
;** Modified by:Chenmingji
;** Modified date:2004-09-17
;** Version:1.01
;** Descriptions:Modified the bus setting to adapt for many common situations
;**//改进了总线,可以根据这里的更改来控制总线的速率
;**------------------------------------------------------------------------------------------------------
;** Modified by:Chenmingji
;** Modified date:2004-09-17
;** Version:1.02
;** Descriptions:Added codes to support the enciphering of the chip
;**//增加了芯片加密
;**------------------------------------------------------------------------------------------------------
;** Modified by:Chenmingji
;** Modified date:2004-09-17
;** Version:1.04
;** Descriptions:Renewed the template, added codes to support more compilers
;**//重建模板,加入更多代码来支持更多的编译
;**------------------------------------------------------------------------------------------------------
;** Modified by:
;** Modified date:
;** Version:
;** Descriptions:
;**
;********************************************************************************************************/
;define the stack size
;定义堆栈的大小
SVC_STACK_LEGTHEQU0
FIQ_STACK_LEGTHEQU0
IRQ_STACK_LEGTHEQU256
ABT_STACK_LEGTHEQU0
UND_STACK_LEGTHEQU0
NoIntEQU 0x80
;定义处理器模式,用户/管理/系统/中断
USR32ModeEQU 0x10
SVC32ModeEQU 0x13
SYS32ModeEQU 0x1f
IRQ32ModeEQU 0x12
FIQ32ModeEQU 0x11
PINSEL2EQU 0xE002C014//定义PINSEL2地址,这个地址的值一般用户不需要改变,和芯片的加密有关
//更改后有可能使得JTAG调试失效,进入芯片加密状态.
BCFG0EQU 0xFFE00000
BCFG1EQU 0xFFE00004
BCFG2EQU 0xFFE00008
BCFG3EQU 0xFFE0000C//定义存储器组配置寄存器
BCFG_16DEF EQU0x10000400;// 16Bit Bus
BCFG_CS3EQU(BCFG_16DEF | (0x01<<00) | (0x07<<05) | (0x07<<11));// 分别是IDCY/WST1/WST2对应读写速率等
;//从第0位开始对其写入0001,
;//从第5位开始写入0111
;//从11位开始写入0111(0x07)/11111(0x1f)
IMPORT __use_no_semihosting_swi
;The imported labels
;引入的外部标号在这声明
IMPORTFIQ_Exception;Fast interrupt exceptions handler 快速中断异常处理程序
IMPORT__main;The entry point to the main function C语言主程序入口
IMPORTTargetResetInit;initialize the target board 目标板基本初始化
;The emported labels
;给外部使用的标号在这声明
EXPORTbottom_of_heap
EXPORTStackUsr
EXPORTReset
EXPORT __user_initial_stackheap
CODE32
AREAvectors,CODE,READONLY
ENTRY
;interrupt vectors
;中断向量表
Reset
LDRPC, ResetAddr
LDRPC, UndefinedAddr
LDRPC, SWI_Addr
LDRPC, PrefetchAddr
LDRPC, DataAbortAddr
DCD0xb9205f80
LDRPC, [PC, #-0xff0]
LDRPC, FIQ_Addr
ResetAddrDCDResetInit
UndefinedAddrDCDUndefined
SWI_AddrDCDSoftwareInterrupt
PrefetchAddrDCDPrefetchAbort
DataAbortAddrDCDDataAbort
NouseDCD0
IRQ_AddrDCD0
FIQ_AddrDCDFIQ_Handler
;未定义指令
Undefined
BUndefined
;软中断
SoftwareInterrupt
BSoftwareInterrupt
;取指令中止
PrefetchAbort
BPrefetchAbort
;取数据中止
DataAbort
BDataAbort
;快速中断
FIQ_Handler
STMFDSP!, {R0-R3, LR}
BLFIQ_Exception
LDMFDSP!, {R0-R3, LR}
SUBSPC,LR,#4
;/*********************************************************************************************************
;** unction name函数名称:InitStack
;** Descriptions功能描述:Initialize the stacks初始化堆栈
;** input parameters输 入:None 无
;** Returned value输 出 :None 无
;** Used global variables 全局变量:None 无
;** Calling modules调用模块:None 无
;**
;** Created by作 者:Chenmingji 陈明计
;** Created Date日 期:2004/02/02 2004年2月2日
;**-------------------------------------------------------------------------------------------------------
;** Modified by修 改:
;** Modified date日 期:
;**-------------------------------------------------------------------------------------------------------
;********************************************************************************************************/
InitStack
MOVR0, LR
;Build the SVC stack
;设置管理模式堆栈
MSRCPSR_c, #0xd3
LDRSP, StackSvc
;Build the IRQ stack
;设置中断模式堆栈
MSRCPSR_c, #0xd2
LDRSP, StackIrq
;Build the FIQ stack
;设置快速中断模式堆栈
MSRCPSR_c, #0xd1
LDRSP, StackFiq
;Build the DATAABORT stack
;设置中止模式堆栈
MSRCPSR_c, #0xd7
LDRSP, StackAbt
;Build the UDF stack
;设置未定义模式堆栈
MSRCPSR_c, #0xdb
LDRSP, StackUnd
;Build the SYS stack
;设置系统模式堆栈
MSRCPSR_c, #0x5f;#0xdf
LDRSP, =StackUsr
MOVPC, R0
;/*********************************************************************************************************
;** unction name函数名称:ResetInit
;** Descriptions功能描述:RESET复位入口
;** input parameters输 入:None 无
;** Returned value输 出 :None 无
;** Used global variables 全局变量:None 无
;** Calling modules调用模块:None 无
;**
;** Created by作 者:Chenmingji 陈明计
;** Created Date日 期:2004/02/02 2004年2月2日
;**-------------------------------------------------------------------------------------------------------
;** Modified by修 改: Chenmingji 陈明计
;** Modified date日 期: 2004/02/02 2004年3月3日
;**-------------------------------------------------------------------------------------------------------
;********************************************************************************************************/
ResetInit
;初始化外部总线控制器,根据目标板决定配置
;
;LDRR0, =PINSEL2
;IF :DEF: EN_CRP
;LDRR1, =0x0f814910
;ELSE
;LDRR1, =0x0f814914
;ENDIF
;STRR1, [R0]
LDRR0, =BCFG0
LDRR1, =0x1000ffef;0x00001046
STRR1, [R0]
LDRR0, =BCFG1
LDRR1, =BCFG_CS3;0x1000ffef;0x1000ffef;;
STRR1, [R0]
LDRR0, =BCFG2
LDRR1, =0x2000ffef
STRR1, [R0]
;LDRR0, =BCFG3
;LDRR1, =0x00000CA0;0x2000ffef
;STRR1, [R0]
BLInitStack;初始化堆栈 Initialize the stack
BLTargetResetInit;目标板基本初始化 Initialize the target board
;跳转到c语言入口 Jump to the entry point of C program
B__main
;/*********************************************************************************************************
;** unction name函数名称:__user_initial_stackheap
;** Descriptions功能描述:Initial the function library stacks and heaps, can not deleted!库函数初始化堆和栈,不能删除
;** input parameters输 入:reference by function library 参考库函数手册
;** Returned value输 出 :reference by function library 参考库函数手册
;** Used global variables 全局变量:None 无
;** Calling modules调用模块:None 无
;**
;** Created by作 者:Chenmingji 陈明计
;** Created Date日 期:2004/02/02 2004年2月2日
;**-------------------------------------------------------------------------------------------------------
;** Modified by
;** Modified date
;**-------------------------------------------------------------------------------------------------------
;********************************************************************************************************/
__user_initial_stackheap
LDRr0,=bottom_of_heap
;LDRr1,=StackUsr
MOVpc,lr
StackSvcDCDSvcStackSpace + (SVC_STACK_LEGTH - 1)* 4
StackIrqDCDIrqStackSpace + (IRQ_STACK_LEGTH - 1)* 4
StackFiqDCDFiqStackSpace + (FIQ_STACK_LEGTH - 1)* 4
StackAbtDCDAbtStackSpace + (ABT_STACK_LEGTH - 1)* 4
StackUndDCDUndtStackSpace + (UND_STACK_LEGTH - 1)* 4
;/*********************************************************************************************************
;** unction name函数名称:CrpData
;** Descriptions功能描述:encrypt the chip
;** input parameters输 入:None 无
;** Returned value输 出 :None 无
;** Used global variables 全局变量:None 无
;** Calling modules调用模块:None 无
;**
;** Created by作 者:Chenmingji 陈明计
;** Created Date日 期:2004/03/27 2004年3月27日
;**-------------------------------------------------------------------------------------------------------
;** Modified by修 改:
;** Modified date日 期:
;**-------------------------------------------------------------------------------------------------------
;********************************************************************************************************/
IF :DEF: EN_CRP
IF. >= 0x1fc
INFO1," The data at 0x000001fc must be 0x87654321. Please delete some source before this line."
ENDIF
CrpData
WHILE . < 0x1fc
NOP
WEND
CrpData1
DCD0x87654321;/*When the Data is 为0x87654321,user code be protected. 当此数为0x87654321时,用户程序被保护 */
ENDIF
;/* 分配堆栈空间 */
AREAMyStacks, DATA, NOINIT, ALIGN=2
SvcStackSpaceSPACESVC_STACK_LEGTH * 4;Stack spaces for Administration Mode 管理模式堆栈空间
IrqStackSpaceSPACEIRQ_STACK_LEGTH * 4;Stack spaces for Interrupt ReQuest Mode 中断模式堆栈空间
FiqStackSpaceSPACEFIQ_STACK_LEGTH * 4;Stack spaces for Fast Interrupt reQuest Mode 快速中断模式堆栈空间
AbtStackSpaceSPACEABT_STACK_LEGTH * 4;Stack spaces for Suspend Mode 中止义模式堆栈空间
UndtStackSpaceSPACEUND_STACK_LEGTH * 4;Stack spaces for Undefined Mode 未定义模式堆栈
AREAHeap, DATA, NOINIT
bottom_of_heapSPACE1
AREAStacks, DATA, NOINIT
StackUsr
END
;/*********************************************************************************************************
;**End Of File
;********************************************************************************************************/