不管C仍是C++,程序的基本單元都是函數,入口點都是 main,這一切能夠在連接時改變但做爲習慣... wait...所謂「習慣」是對軟件開發者而言,as、ld這些工具是看不到什麼函數的,到了cpu只有依次對齊的機器碼而已。但C的影響如此之深以至有了專門的寄存器 sp 作棧指針,換言之,要搞函數先備棧。css
C/C++不可能本身設置棧指針的,一般這由在 main 以前執行的彙編代碼完成(head.s):linux
.text .global _start _start: ldr sp, =0x40001000 @ 設置堆棧,注意:不能大於4k, 由於如今可用的內存只有4K bl main @ 調用C程序中的main函數 _end: b _end
上面把 sp 設置到 0x40001000說明個人板子要從nor 啓動,若是是從nand啓動片內ram 在0~0x1000這裏就只能寫c++
ldr sp, =0x1000
更詳細的參考上一篇《mini2440 點燈》。shell
有了這個頭以後下來就該 C/C++ 展身手了(led.cpp):sass
int main() { unsigned long* dog = reinterpret_cast<unsigned long*>(0x53000000); *dog = 0; unsigned long* gpbcon = reinterpret_cast<unsigned long*>(0x56000010); *gpbcon = 0x15400; unsigned long* gpbdata = reinterpret_cast<unsigned long*>(0x56000014); *gpbdata = 0; return 0; }
g++ 要求 main 返回 int,c++ 要求常量賦值要有類型轉換。編譯以下:
函數
arm-linux-gcc -c -o head.o head.s arm-linux-g++ -c -o led.o led.cpp arm-linux-ld -Ttext 0x40000000 -g led.o head.o -o led++.elf
調試過程同《mini2440 點燈》。工具
下面讓咱們看看這個程序的效率吧優化
arm-linux-objdump -D -m arm led.elf > led.dis arm-linux-objdump -D -m arm led++.elf > led++.dis
led.dis 和 led++.dis 分別爲純彙編和C++編譯獲得的可視機器碼結果,先看led.dis編碼
led.elf: file format elf32-littlearm Disassembly of section .text: 40000000 <_start>: 40000000: e3a00453 mov r0, #1392508928 ; 0x53000000 40000004: e3a01000 mov r1, #0 ; 0x0 40000008: e5801000 str r1, [r0] 4000000c: e59f0010 ldr r0, [pc, #16] ; 40000024 <_end+0x4> 40000010: e3a01b55 mov r1, #87040 ; 0x15400 40000014: e4801004 str r1, [r0], #4 40000018: e3a01000 mov r1, #0 ; 0x0 4000001c: e4801004 str r1, [r0], #4 40000020 <_end>: 40000020: eafffffe b 40000020 <_end> 40000024: 56000010 .word 0x56000010 Disassembly of section .ARM.attributes: 00000000 <.ARM.attributes>: 0: 00001741 andeq r1, r0, r1, asr #14 4: 61656100 cmnvs r5, r0, lsl #2 8: 01006962 tsteq r0, r2, ror #18 c: 0000000d andeq r0, r0, sp 10: 00543405 subseq r3, r4, r5, lsl #8 14: 01080206 tsteq r8, r6, lsl #4
下來是led++.dis.net
led++.elf: file format elf32-littlearm Disassembly of section .text: 40000000 <main>: 40000000: e52db004 push {fp} ; (str fp, [sp, #-4]!) 40000004: e28db000 add fp, sp, #0 ; 0x0 40000008: e24dd014 sub sp, sp, #20 ; 0x14 4000000c: e3a03453 mov r3, #1392508928 ; 0x53000000 40000010: e50b3010 str r3, [fp, #-16] 40000014: e51b2010 ldr r2, [fp, #-16] 40000018: e3a03000 mov r3, #0 ; 0x0 4000001c: e5823000 str r3, [r2] 40000020: e3a03456 mov r3, #1442840576 ; 0x56000000 40000024: e2833010 add r3, r3, #16 ; 0x10 40000028: e50b300c str r3, [fp, #-12] 4000002c: e51b200c ldr r2, [fp, #-12] 40000030: e3a03b55 mov r3, #87040 ; 0x15400 40000034: e5823000 str r3, [r2] 40000038: e3a03456 mov r3, #1442840576 ; 0x56000000 4000003c: e2833014 add r3, r3, #20 ; 0x14 40000040: e50b3008 str r3, [fp, #-8] 40000044: e51b2008 ldr r2, [fp, #-8] 40000048: e3a03000 mov r3, #0 ; 0x0 4000004c: e5823000 str r3, [r2] 40000050: e3a03000 mov r3, #0 ; 0x0 40000054: e1a00003 mov r0, r3 40000058: e28bd000 add sp, fp, #0 ; 0x0 4000005c: e8bd0800 pop {fp} 40000060: e12fff1e bx lr 40000064 <_start>: 40000064: e59fd004 ldr sp, [pc, #4] ; 40000070 <_end+0x4> 40000068: ebffffe4 bl 40000000 <main> 4000006c <_end>: 4000006c: eafffffe b 4000006c <_end> 40000070: 40001000 .word 0x40001000 Disassembly of section .ARM.exidx: 40000074 <__data_start-0x8008>: 40000074: 7fffff8c svcvc 0x00ffff8c 40000078: 00000001 andeq r0, r0, r1 Disassembly of section .comment: 00000000 <.comment>: 0: 43434700 movtmi r4, #14080 ; 0x3700 4: 5328203a teqpl r8, #58 ; 0x3a 8: 6372756f cmnvs r2, #465567744 ; 0x1bc00000 c: 20797265 rsbscs r7, r9, r5, ror #4 10: 202b2b47 eorcs r2, fp, r7, asr #22 14: 6574694c ldrbvs r6, [r4, #-2380]! 18: 30303220 eorscc r3, r0, r0, lsr #4 1c: 2d337138 ldfcss f7, [r3, #-224]! 20: 20293237 eorcs r3, r9, r7, lsr r2 24: 2e332e34 mrccs 14, 1, r2, cr3, cr4, {1} 28: Address 0x00000028 is out of bounds. Disassembly of section .ARM.attributes: 00000000 <.ARM.attributes>: 0: 00002741 andeq r2, r0, r1, asr #14 4: 61656100 cmnvs r5, r0, lsl #2 8: 01006962 tsteq r0, r2, ror #18 c: 0000001d andeq r0, r0, sp, lsl r0 10: 00543405 subseq r3, r4, r5, lsl #8 14: 01080206 tsteq r8, r6, lsl #4 18: 01140412 tsteq r4, r2, lsl r4 1c: 03170115 tsteq r7, #1073741829 ; 0x40000005 20: 01190118 tsteq r9, r8, lsl r1 24: 061e021a undefined
一樣的事情 .text 段長了一倍多,編譯 led.cpp 是加個 -O2再看看結果
led++.elf: file format elf32-littlearm Disassembly of section .text: 40000000 <main>: 40000000: e3a00000 mov r0, #0 ; 0x0 40000004: e3a01456 mov r1, #1442840576 ; 0x56000000 40000008: e3a03453 mov r3, #1392508928 ; 0x53000000 4000000c: e3a02b55 mov r2, #87040 ; 0x15400 40000010: e5830000 str r0, [r3] 40000014: e5812010 str r2, [r1, #16] 40000018: e5810014 str r0, [r1, #20] 4000001c: e12fff1e bx lr 40000020 <_start>: 40000020: e59fd004 ldr sp, [pc, #4] ; 4000002c <_end+0x4> 40000024: ebfffff5 bl 40000000 <main> 40000028 <_end>: 40000028: eafffffe b 40000028 <_end> 4000002c: 40001000 .word 0x40001000 Disassembly of section .ARM.exidx: 40000030 <__data_start-0x8008>: 40000030: 7fffffd0 svcvc 0x00ffffd0 40000034: 00000001 andeq r0, r0, r1 Disassembly of section .comment: 00000000 <.comment>: 0: 43434700 movtmi r4, #14080 ; 0x3700 4: 5328203a teqpl r8, #58 ; 0x3a 8: 6372756f cmnvs r2, #465567744 ; 0x1bc00000 c: 20797265 rsbscs r7, r9, r5, ror #4 10: 202b2b47 eorcs r2, fp, r7, asr #22 14: 6574694c ldrbvs r6, [r4, #-2380]! 18: 30303220 eorscc r3, r0, r0, lsr #4 1c: 2d337138 ldfcss f7, [r3, #-224]! 20: 20293237 eorcs r3, r9, r7, lsr r2 24: 2e332e34 mrccs 14, 1, r2, cr3, cr4, {1} 28: Address 0x00000028 is out of bounds. Disassembly of section .ARM.attributes: 00000000 <.ARM.attributes>: 0: 00002741 andeq r2, r0, r1, asr #14 4: 61656100 cmnvs r5, r0, lsl #2 8: 01006962 tsteq r0, r2, ror #18 c: 0000001d andeq r0, r0, sp, lsl r0 10: 00543405 subseq r3, r4, r5, lsl #8 14: 01080206 tsteq r8, r6, lsl #4 18: 01140412 tsteq r4, r2, lsl r4 1c: 03170115 tsteq r7, #1073741829 ; 0x40000005 20: 01190118 tsteq r9, r8, lsl r1 24: 021e021a andseq r0, lr, #-1610612735 ; 0xa0000001
注意對比一下 main 裏的彙編碼(機器碼)和led.s 中的,可見編譯器優化仍是蠻有效的。