RVDS集成环境下CodeWarrior配置如下:
Linker(链接)设置
RealView Linker->Output:
Linkertype选Simple;Simple image中RO Base填0x50200000。
RealView Linker->Layout:
Object/Symbol填Startup.o;Section填start。
在应用程序设计中,如果所有任务均有汇编语言来完成,其工作量是可想而知的,而且不利于系统升级或应用软件移植。但是,ARM体系结构支持C/C++与汇编的混合编程,在一个完整的系统中,除了CPU初始化部分用汇编语言完成之外,其主要的编程任务一般用C/C++完成。
一、基础知识
1.在C/C++中嵌入汇编指令
__asm{}
2.汇编访问C/C++变量
使用全局变量。
3.C/C++调用汇编函数
C中声明函数原型,并加extern关键字;
汇编中用EXPORT导出函数名,用函数名作为汇编代码段的标识、汇编代码段最后用mov pc,lr返回。
4.汇编程序中调用C/C++函数
在汇编中IMPORT对应的函数名,将C的代码放在一个独立的C文件中进行编译。
二、汇编代码段完成工作
RO设为0x5020 0138 //RO段,代码段结束地址(起始0x5020 0000)
R1设为0x5020 0478 //ZI段,未初始化全局变量段结束地址
R2设为0x0000 0000 //初始化全局变量
R3设为0x5020 0138 //ZI段,未初始化全局变量段起始地址
1.Startup.s
; 启动文件。初始化C程序的运行环境,然后进入C程序代码。 ;导入连接器事先定义好的运行域中三个段变量 ;ARM的可执行映像文件由RO、RW、ZI三个段组成 ;RO为代码段,RW为已初始化的全局变量,ZI为未初始化的全局变量 preserve8 IMPORT |Image$$RO$$Limit| ; RO段结束地址 IMPORT |Image$$RW$$Base| ; RW段起始地址 IMPORT |Image$$ZI$$Base| ; ZI段起始地址 IMPORT |Image$$ZI$$Limit| ; ZI段结束地址 IMPORT Main ; 声明C程序中的Main()函数 AREA Start,CODE,READONLY ; 声明代码段Start ENTRY ; 标识程序入口 CODE32 ; 声明32位ARM指令 USR_STACK_LEGTH EQU 128 ; 初始化C程序的运行环境 LDR R0,=|Image$$RO$$Limit| LDR R1,=|Image$$RW$$Base| LDR R3,=|Image$$ZI$$Base| CMP R0,R1 BEQ LOOP1 LOOP0 CMP R1,R3 LDRCC R2,[R0],#4 STRCC R2,[R1],#4 BCC LOOP0 LOOP1 LDR R1,=|Image$$ZI$$Limit| MOV R2,#0 LOOP2 CMP R3,R1 STRCC R2,[R3],#4 BCC LOOP2 ;设置系统模式堆栈,SP/r13寄存器 ;MSR CPSR_c, #0xdf LDR SP, StackUsr BL Main ; 跳转到C程序代码Main()函数 StackUsr DCD UsrStackSpace + (USR_STACK_LEGTH - 1)*4 AREA MyStacks, DATA, NOINIT, ALIGN=2 UsrStackSpace SPACE USR_STACK_LEGTH * 4 ; 用户(系统)模式堆栈空间 END2.main.c
void Main(void){ int c[20]; c[0] = 6; c[1] = 7; c[2] = 8; c[18] = 5; c[19] = 3 }值得注意的是,C语言会自动为C函数中经常使用int类型变量设置成resigter int。这样的局部变量就不是使用堆栈空间的了,而就是直接使用寄存器。
因此,上边C程序、我用的是数组。
====================================================================================================================================
如果不想更深理解、就要抛开RVDS的IDE;直接在DOS下make编译。完了直接运行AXD在load时选*.axf即可。
以下是基于Window下armmcc编译器的Makefile:
all: armasm -o Startup.o Startup.s --debug --keep --cpu=ARM1176JZF-S armcc -c main.o main.c --debug --cpu=ARM1176JZF-S -O0 armlink -o inclc.axf Startup.o main.o --entry Main --ro_base=0x50200000 --first=Startup.o(start) fromelf -o inclc.bin --bin inclc.axf clean: del *.o *.axf *.bin #armasm -o Startup.o Startup.s --debug --keep --cpu=ARM1176JZF-S #armcc -c main.o main.c --debug --cpu=ARM1176JZF-S -O0 #armlink -o inclc.axf Startup.o main.o --entry Main --ro_base=0x50200000 --first=Startup.o(start) #fromelf -o inclc.bin --bin inclc.axf