以前曾经使用GNU的 arm-linux-* 工具链在命令行模式下写过ARM的代码,前段时间安装了Keil的mdk-arm 开发工具,心血来潮想试试在命令行下能不能开发ARM,结果成功了。我所测试的代码非常简单,只是一个实验,具有实用价值的代码没有测试过。当然,如果有了图形界面的IDE再使用命令行开发,是多此一举、舍近求远了,这只是个人爱好吧。我的环境:windows7旗舰版;Keil arm-mdk V4.2;Cygwin(已经安好了make等基本工具)模拟开发的器件是arm最近推出的cortex-m4(带DSP处理单元).整个工程只包含4个文件:启动文件head.s、C文件main.c、分散加载文件start.sct、Makefile。下面是各个文件的内容。head.s     1          IMPORT main     2          AREA startup,CODE     3          THUMB     4          DCD 0x20000000     5          DCD reset     6  reset   PROC     7          ENTRY     8          ; CPACR is located at address 0xE000ED88     9          LDR.W R0, =0xE000ED88    10          ; Read CPACR    11          LDR R1, [R0]    12          ; Set bits 20-23 to enable CP10 and CP11 coprocessors    13          ORR R1, R1, #(0xF     14          ; Write back the modified value to the CPACR    15          STR R1, [R0]    16          push {r0-r1}    17          LDR R0,=main    18          BL main    19          B .    20          ENDP    21          ALIGN    22          END其中的第8-15行是开启FPU处理单元的代码(针对有FPU的处理器),第16行用来测试堆栈的情况;第6行和第20行的PROC、ENDP告诉编译器这是个执行程序段(以便编译器在编译时把跳转地址的bit 0变为单数,例如第5行变成reset所在的地址+1,这是因为cortex-m4只支持thumb代码,在向thumb代码跳转时PC地址bit0必须为1)。main.c     1 int main()     2 {     3 float a=3.14159;     4 float b=2.987;     5 float c;     6 c=a*b*b;     7 return (int)c;     8 }这里使用了浮点运算,以测试是否能正确编译浮点运算为FPU的硬件指令。start.sct1 ROMLOAD 0x0 0x4000 2 { 3 EXEC_RO 0x0 4 { 5 head.o(startup, +first) 6 *(+RO) 7 8 } 9 RAM 0x1FFF8000 10 { 11 *(+RW,+ZI) 12 } 13 }分散加载文件,把启动代码放到最开始。Makefile1 main.bin:main.c head.s 2 armcc --cpu cortex-m4.fp -O0 --apcs=interwork --li -g -c -I "C:\Keil\ARM\CMSIS\Include" main.c -o main.o 3 armasm --cpu cortex-m4.fp --li --apcs=interwork -I "C:\Keil\ARM\CMSIS\Include" head.s -o head.o 4 armlink --cpu cortex-m4.fp --no_startup --libpath "C:\Keil\ARM\RV31\LIB" --scatter start.sct head.o main.o -o main.axf 5 fromelf --bin --output main.bin main.axf 6 fromelf main.axf -c|sed -n '/Section #1/,$$p'|sed '/Section #2/,$$d'>_main.list 7 #dos2unix _main.list 8 clean: 9 rm *.o *.axf *.list *.bin第4行这里有个--no_startup需要说明一下,在不添加这个选项时,Keil会“自作聪明”的在生成的汇编代码中添加一些代码,这些代码也许是我们并不想要的,所以增加这个--no_startup选项后就不再有这些代码了。第6行后面的sed是从调试信息中过滤出我们所需要看的部分,其它的被滤除。四个文件都具备后,在当前目录下执行make指令(会有两个警告信息,可以忽略),便可生成main.axf的调试映像了,可以在keil中调试;_main.list是生成的反汇编代码,内容如下:** Section #1 'EXEC_RO' (SHT_PROGBITS) [SHF_ALLOC + SHF_EXECINSTR]        Size   : 88 bytes (alignment 4)        Address: 0x00000000        $d        startup                0x00000000:     20000000        ...DCD    536870912                0x00000004:     00000009        ....DCD     9        $t        $v0        reset                0x00000008:     f8df0014        ....LDR.W   r0,[pc,#20] ; [0x20] = 0xe000ed88                0x0000000c:     6801            .hLDR     r1,[r0,#0]                0x0000000e:     f4410170        A.p.    ORR       r1,r1,#0xf00000                0x00000012:     6001            .`STR     r1,[r0,#0]                0x00000014:     b403            ..PUSH   {r0,r1}                0x00000016:     4803            .HLDR     r0,[pc,#12] ; [0x24] = 0x29                0x00000018:     f000f806        ....BL         main ; 0x28                0x0000001c:     e7fe            ..B             0x1c ; reset + 20        $d                0x0000001e:     0000            ..DCW   0                0x00000020:     e000ed88        ....DCD     3758157192                0x00000024:     00000029        )...DCD     41        $t        .text        main                0x00000028:     eddf1a09        ....    VLDR     s3,[pc,#36] ; [0x50] = 0x40490fd0                0x0000002c:     eef00a61        ..a.    VMOV.F32 s1,s3                0x00000030:     eddf1a08        ....    VLDR     s3,[pc,#32] ; [0x54] = 0x403f2b02                0x00000034:     eeb00a61        ..a.    VMOV.F32 s0,s3                0x00000038:     ee601a80        `...    VMUL.F32 s3,s1,s0                0x0000003c:     ee611a80        a...    VMUL.F32 s3,s3,s0                0x00000040:     eeb01a61        ..a.    VMOV.F32 s2,s3                0x00000044:     eefd1ac1        ....    VCVT.S32.F32 s3,s2                0x00000048:     ee110a90        ....    VMOV     r0,s3                0x0000004c:     4770            pGBX       lr        $d                0x0000004e:     0000            ..DCW   0                0x00000050:     40490fd0        ..I@    DCD     1078530000                0x00000054:     403f2b02        .+?@    DCD     1077881602
09-03 20:54