mini2440 點燈++

不管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 中的,可見編譯器優化仍是蠻有效的。

相關文章
相關標籤/搜索