mini2440 点灯++

无论C还是C++,程序的基本单元都是函数,入口点都是 main,这一切可以在链接时改变但作为习惯... wait...所谓“习惯”是对软件开发者而言,as、ld这些工具是看不到什么函数的,到了cpu只有依次对齐的机器码而已。但C的影响如此之深以致有了专门的寄存器 sp 做栈指针,换言之,要搞函数先备栈。

C/C++不可能自己设置栈指针的,通常这由在 main 之前执行的汇编代码完成(head.s):

.text
.global _start
_start:
    ldr sp, =0x40001000     @ 设置堆栈,注意:不能大于4k, 因为现在可用的内存只有4K
    bl  main                @ 调用C程序中的main函数
_end:
    b   _end

上面把 sp 设置到 0x40001000说明我的板子要从nor 启动,如果是从nand启动片内ram 在0~0x1000这里就只能写

    ldr sp, =0x1000

更详细的参考上一篇《mini2440 点灯》。

有了这个头之后下来就该 C/C++ 展身手了(led.cpp):

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

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 中的,可见编译器优化还是蛮有效的。

你可能感兴趣的:(g++,SP,-O2)