ADS简单程序编译分析

来源:互联网 发布:安卓2.2软件 编辑:程序博客网 时间:2024/05/20 08:27

前言

最近准备将公司的产品进行更新,目前的产品是ucos操作系统混合了产品程序一起烧写到LPC2148的512k FLASH内部,这样做有个弊端,就是一旦产品程序出了错误,无法让客户自行更新程序,因此希望改成操作系统与产品程序分离,在必要的时候执行将tf卡内部的程序烧写道FLASH内部进行产品程序更新。操作系统程序一旦固化入FLASH则尽量不去修改,目前没有设计更新操作系统的方法。
如此一来,512K FLASH的底层空间由操作系统占用,程序上电从0地址运行,此时为操作系统端,此后程序将运行到能够切换到用户状态加载程序处。操作系统把需要的程序接口地址写入一个约定地址(比如读取TF卡),并没有使用swi(软件中断),因为这种形式修改起来方便,都是现成的程序。如果将来再次升级系统可以改变为swi调用系统函数。
系统按照与用户程序约定的地址调用用户程序,用户调用系统程序时也使用约定的地址寻找程序地址,因此首先需要了解ADS是如何编译程序的,因此进行了下面的分析:

C代码

首先,用ADS创建一个工程,输入以下代码:

void fun1(){    char *p;    int i;    p = (char *)0x40004000;    for(i = 0; i < 16; i++)     {        *p = i;        p++;    }}int main(){    fun1();    return 1;}

在编译器设置里,将Linker-ARM linker下的link type设置为simple,RO Base设置为0x29c00,这是程序将来将要烧写到的位置。RW Base设置为0x40003000这是将来保存变量的区域,此后在Linker-ARM fromELF功能里选择生成Text Information,设置好文件名,将会产生出文本文档形式的ELF文件详细说明,其中我们需要关注的是将要烧写到ROM中的代码段,附录里是摘抄出来的完整的编译后的汇编代码。

汇编程序分析

下面是对程序的分析:
首先,因为设置了RO Base为0x29c00,因此在执行此程序的时候,内存地址应为0x29c00,且PC(指令计数器)也应当指向此处。

__main$a!!!    0x00029c00:    e28f8090    ....    ADD      r8,pc,#0x90 ; #0x29c98    0x00029c04:    e898000f    ....    LDMIA    r8,{r0-r3}    0x00029c08:    e0800008    ....    ADD      r0,r0,r8    0x00029c0c:    e0811008    ....    ADD      r1,r1,r8    0x00029c10:    e0822008    . ..    ADD      r2,r2,r8    0x00029c14:    e0833008    .0..    ADD      r3,r3,r8    0x00029c18:    e240b001    ..@.    SUB      r11,r0,#1    0x00029c1c:    e242c001    ..B.    SUB      r12,r2,#1

可以看到第一行即程序的起始地址就是这个数,将来烧写的时候,烧写器会根据烧写地址放入对应位置(LPC2148的前512kb字节为Flash,属于非易失存储器,因此程序保存在这个范围内)。第一条语句将pc加上0x90放入r8,此时pc指向的是下一个取命令地址,也可能是因为一次取16字节命令,所以pc的值为0x29c08,则r8此后为0x29c98。下一条语句的意思是从r8开始,取连续的4个地址的值,放入r0-r3。

_region_table$d    0x00029c98:    0000032c    ,...    DCD    812    0x00029c9c:    00000350    P...    DCD    848    0x00029ca0:    00000350    P...    DCD    848    0x00029ca4:    00000368    h...    DCD    872

因此r0=812, r1=848, r2=848, r3=872。
后面的几个语句为r0=r0+r8…r3=r3+r8,r11=r0-1,r12=r2-1
通过计算,r0=0x29fc4, r1=0x29fe8, r2=0x29fe8, r3=0x2a000,可以看出来,这应该还是程序段内部的地址,他们对应的是下面的代码:

Region$$Table$$Base$d    0x00029fc4:    00000000    ....    DCD    0    0x00029fc8:    00000000    ....    DCD    0    0x00029fcc:    00000000    ....    DCD    0    0x00029fd0:    0002a000    ....    DCD    172032    0x00029fd4:    40003000    .0.@    DCD    1073754112    0x00029fd8:    00000000    ....    DCD    0    0x00029fdc:    0002a000    ....    DCD    172032    0x00029fe0:    40003000    .0.@    DCD    1073754112    0x00029fe4:    00000000    ....    DCD    0Region$$Table$$LimitZISection$$Table$$Base    0x00029fe8:    0002a000    ....    DCD    172032    0x00029fec:    00000000    ....    DCD    0    0x00029ff0:    40003000    .0.@    DCD    1073754112    0x00029ff4:    00000000    ....    DCD    0    0x00029ff8:    40003000    .0.@    DCD    1073754112    0x00029ffc:    00000060    `...    DCD    96ZISection$$Table$$Limit

可以看出分别对应了一个叫做Region表的起始和结束地址,以及一个叫做ZISection表的起始和结束地址。这大概对应了程序中的全局数据段以及函数变量段,他们的区别就是一个要全程保留且要初始化,分配在堆里面,另一个在函数内才会被分配空间,即在堆栈内分配空间,一旦函数释放了数据就没有义务被保存,初始化的时候需要清零。从名字可以看出来ZISection应当对应了Zero Initial Section,所以是函数变量的空间。他们都有几个特殊数字,分别对应了编译器指定的RO Base地址0x40003000,以及代码段的结尾0x2a000,功能后面再分析。
后面的代码为:

_move_region    0x00029c20:    e1500001    ..P.    CMP      r0,r1    0x00029c24:    0a00000e    ....    BEQ      _zero_region  ; 0x29c64    0x00029c28:    e8b00070    p...    LDMIA    r0!,{r4-r6}    0x00029c2c:    e1540005    ..T.    CMP      r4,r5    0x00029c30:    0afffffa    ....    BEQ      _move_region  ; 0x29c20    0x00029c34:    e3140001    ....    TST      r4,#1    0x00029c38:    1084400b    .@..    ADDNE    r4,r4,r11    0x00029c3c:    e3150001    ....    TST      r5,#1    0x00029c40:    1085500b    .P..    ADDNE    r5,r5,r11    0x00029c44:    e3150002    ....    TST      r5,#2    0x00029c48:    10855009    .P..    ADDNE    r5,r5,r9    0x00029c4c:    e3c55003    .P..    BIC      r5,r5,#3

此段的名称可以看出来是移动region表,前二行为比较r0,r1,若相等说明没有region表,则跳到_zero_region执行。

LDMIA    r0!,{r4-r6}

此句多了一个’!’符号,表示执行后将最终地址放入r0。参考region表,可以知道r4-r6均为0,r0=0x00029fd0。

    0x00029c2c:    e1540005    ..T.    CMP      r4,r5    0x00029c30:    0afffffa    ....    BEQ      _move_region  ; 

若r4,r5相等则跳回_move_region执行,此时r0的值已经改变,则再次运行到此的时候,r4=172032(0x2a000), r5=1073754112(0x40004000), r6=0, r0=0x00029fdc,此后由于r4!=r5,程序向下进行。

    0x00029c34:    e3140001    ....    TST      r4,#1    0x00029c38:    1084400b    .@..    ADDNE    r4,r4,r11    0x00029c3c:    e3150001    ....    TST      r5,#1    0x00029c40:    1085500b    .P..    ADDNE    r5,r5,r11    0x00029c44:    e3150002    ....    TST      r5,#2    0x00029c48:    10855009    .P..    ADDNE    r5,r5,r9    0x00029c4c:    e3c55003    .P..    BIC      r5,r5,#3

TST的意思是,r4与后面的立即数位与,并根据结果设置标志位,由于r4没有设置最低位,因此结果为0,后面的ADDNE将不会执行。
BIC是清位操作,等同于等同于 R5 &=~(0x03)
在此程序中实际上此段未进行什么实质处理。

_move_loop    0x00029c50:    e2566004    .`V.    SUBS     r6,r6,#4    0x00029c54:    24947004    .p.$    LDRCS    r7,[r4],#4    0x00029c58:    24857004    .p.$    STRCS    r7,[r5],#4    0x00029c5c:    8afffffb    ....    BHI      _move_loop  ; 0x29c50    0x00029c60:    eaffffee    ....    B        _move_region  ; 0x29c20

第一句SUBS r6,r6,#4等同于r6=r6-4,并根据结果设置标志位。减法是将操作数求补后相加,这里由于执行前r6=0因此将不设置标志位。LDRCS r7,[r4],#4找不到对应的指令说明,但根据字面意思可以得到,如果标志位被置位,则执行r7=[r4](即r4指向地址的值),r4=r4+4,这里应当不会执行。同理下面一句r7,[r5],#4也不执行。BHI _move_loop如果进位位被置位则跳转到_move_loop此处也不执行。
此后依然跳转回_move_region执行,将会按照前面解释的过程再执行一次,此次运行到跳转回_move_region的位置时,r0=0x00029fe8,与r1相等了,程序将跳出_move_region转到_zero_region执行。可以看出,此段程序根据region中段的数量可以进行多次拷贝,本程序共拷贝了2次。

_zero_region    0x00029c64:    e1520003    ..R.    CMP      r2,r3    0x00029c68:    0b000018    ....    BLEQ     __rt_entry  ; 0x29cd0    0x00029c6c:    e3a07000    .p..    MOV      r7,#0    0x00029c70:    e8b20030    0...    LDMIA    r2!,{r4,r5}    0x00029c74:    e3140001    ....    TST      r4,#1    0x00029c78:    1084400c    .@..    ADDNE    r4,r4,r12    0x00029c7c:    e3140002    ....    TST      r4,#2    0x00029c80:    10844009    .@..    ADDNE    r4,r4,r9    0x00029c84:    e3c44003    .@..    BIC      r4,r4,#3_zero_loop    0x00029c88:    e2555004    .PU.    SUBS     r5,r5,#4    0x00029c8c:    24847004    .p.$    STRCS    r7,[r4],#4    0x00029c90:    8afffffc    ....    BHI      _zero_loop  ; 0x29c88    0x00029c94:    eafffff2    ....    B        _zero_region  ; 0x29c64

与region一样,首先比较r2,r3,若相等就跳转到__rt_entry。BL是需要返回值得跳转,此语句默认设置R14作为返回值地址(在程序中不会显式的看到此操作)。实际上此段程序将会循环三次,直到第三次,r5=96,将会连续写24个0到0x40003000开头的位置。此后r2=r3=0x2a000,程序跳转到__rt_entry。

__rt_entry$a.text    0x00029cd0:    eb000046    F...    BL       __rt_stackheap_init  ; 0x29df0    0x00029cd4:    eb0000ad    ....    BL       $Ven$AT$L$$__rt_lib_init  ; 0x29f90    0x00029cd8:    e59fc01c    ....    LDR      r12,0x29cfc

BL为要求返回的跳转,将会把PC的值保存在r14中,作为以后返回此处的地址。可见先调用了__rt_stackheap_init,位于地址0x29df0。此后调用了$Ven$AT$L$$__rt_lib_init,位于地址0x29f90,最后把0x29cfc赋值到r12。下面分析两个函数的功能:
1.函数__rt_stackheap_init

__rt_stackheap_init$a    0x00029df0:    e1a0500e    .P..    MOV      r5,r14    0x00029df4:    eb000047    G...    BL       __user_libspace  ; 0x29f18    0x00029df8:    e1a0e005    ....    MOV      r14,r5

首先,把r14保存起来,作为以后返回的地址,此后调用__user_libspace,

__user_libspace$a    0x00029f18:    e59f0000    ....    LDR      r0,0x29f20    0x00029f1c:    e12fff1e    ../.    BX       r14$d    0x00029f20:    40003000    .0.@    DCD    1073754112

此函数功能很简单,就是把0x40003000放入r0后返回。下面回到__rt_stackheap_init,恢复此前保存的r14值,r5可以用作他处了。

    0x00029dfc:    e1a04000    .@..    MOV      r4,r0    0x00029e00:    e1a0100d    ....    MOV      r1,r13    0x00029e04:    e1a0300a    .0..    MOV      r3,r10

r4=0x40003000,r1=r13,r3=r10其中arm通常使用r13作为sp(堆栈)地址寄存器,所以r1表示的是当前堆栈的底部,r10的作用暂时未知,r3被赋值后未见何特殊操作。

    0x00029e08:    e3c00007    ....    BIC      r0,r0,#7    0x00029e0c:    e280d060    `...    ADD      r13,r0,#0x60    0x00029e10:    e92d4010    .@-.    STMFD    r13!,{r4,r14}    0x00029e14:    eb000043    C...    BL       __user_initial_stackheap  ; 0x29f28

BIC为清位操作,把r0低三位清零,这估计是因为至少保证字节对齐。把r13(堆栈)设置为r0+0x60的位置,此处可以看出,0x60=96,而在前面的_zero_region中已经开辟出了一个96字节的,从0x40003000开始的区域,因此本程序的栈底为0x40003060(注意堆栈是向下增长地址的),STMFD r13!,{r4,r14}表示入栈操作,将r4,r14压入堆栈,此时栈底将指向0x40003058。下面跳转到__user_initial_stackheap,从名字可以看出是初始化用户的堆栈和堆。

__user_initial_stackheap$a    0x00029f28:    e92d4000    .@-.    STMFD    r13!,{r14}    0x00029f2c:    e24dd014    ..M.    SUB      r13,r13,#0x14    0x00029f30:    e1a0100d    ....    MOV      r1,r13    0x00029f34:    e28d2004    . ..    ADD      r2,r13,#4    0x00029f38:    e5812000    . ..    STR      r2,[r1,#0]    0x00029f3c:    e3a00016    ....    MOV      r0,#0x16    0x00029f40:    ef123456    V4..    SWI      0x123456    0x00029f44:    e59d0004    ....    LDR      r0,[r13,#4]    0x00029f48:    e59d100c    ....    LDR      r1,[r13,#0xc]    0x00029f4c:    e59d2008    . ..    LDR      r2,[r13,#8]    0x00029f50:    e59d3010    .0..    LDR      r3,[r13,#0x10]    0x00029f54:    e3500000    ..P.    CMP      r0,#0    0x00029f58:    059f000c    ....    LDREQ    r0,0x29f6c    0x00029f5c:    e28dd014    ....    ADD      r13,r13,#0x14    0x00029f60:    e8bd4000    .@..    LDMFD    r13!,{r14}    0x00029f64:    e12fff1e    ../.    BX       r14$d$f    0x00029f68:    00000009    ....    DCD    9_RW_Limit    0x00029f6c:    40003060    `0.@    DCD    1073754208

将r14压入用户栈,将栈向下移动20个字节,把栈底保存到r1,此时栈底为0x40003034。r2=0x40003038,并把r2的值存入r1指向的地址。此后的

    0x00029f3c:    e3a00016    ....    MOV      r0,#0x16    0x00029f40:    ef123456    V4..    SWI      0x123456

具体应该是调用了软中断,这里暂时判断为没有任何作用,直接返回,也可能不返回,因为没有设置软中断。

    0x00029f44:    e59d0004    ....    LDR      r0,[r13,#4]    0x00029f48:    e59d100c    ....    LDR      r1,[r13,#0xc]    0x00029f4c:    e59d2008    . ..    LDR      r2,[r13,#8]    0x00029f50:    e59d3010    .0..    LDR      r3,[r13,#0x10]

r0=[0x40003038],r1= [0x40003040],r2=[0x4000303c],r3=[0x40003044]此4个地址应当都对应了0,因此后面的CMP语句将会得到相等的结果,则执行LDREQ r0,0x29f6c因此r0=40003060,后面恢复r13 ,r14,并返回上级调用。此段函数大概就是检查栈区是否清零过,并把r0设置为栈顶的值,返回,程序回到__rt_stackheap_init继续执行。

    0x00029e18:    e8bd4010    .@..    LDMFD    r13!,{r4,r14}    0x00029e1c:    e3c1d007    ....    BIC      r13,r1,#7    0x00029e20:    e3a06000    .`..    MOV      r6,#0    0x00029e24:    e3a07000    .p..    MOV      r7,#0    0x00029e28:    e3a08000    ....    MOV      r8,#0    0x00029e2c:    e3a0b000    ....    MOV      r11,#0    0x00029e30:    e1a0c004    ....    MOV      r12,r4

让r4,r14的值出栈,将r1低三位清零赋值给r13,等于恢复r13的初始值且8字节对齐。r6=r7=r8=r11=0,r12=0x40003000。

    0x00029e34:    e8ac09c0    ....    STMIA    r12!,{r6-r8,r11}    0x00029e38:    e8ac09c0    ....    STMIA    r12!,{r6-r8,r11}    0x00029e3c:    e8ac09c0    ....    STMIA    r12!,{r6-r8,r11}    0x00029e40:    e8ac09c0    ....    STMIA    r12!,{r6-r8,r11}

此处程序执行后,r12=0x40003040,r6-r8,r11均为0

    0x00029e44:    e92d4013    .@-.    STMFD    r13!,{r0,r1,r4,r14}

将r0,r1,r4,r14入栈,r13随之改变

    0x00029e48:    e3a00000    ....    MOV      r0,#0    0x00029e4c:    e3a01000    ....    MOV      r1,#0    0x00029e50:    ebffffff    ....    BL       0x29e54

r0=0,r1=0,r14=0x00029e54

    0x00029e54:    e2811040    @...    ADD      r1,r1,#0x40    0x00029e58:    e0802001    . ..    ADD      r2,r0,r1    0x00029e5c:    e2822f44    D/..    ADD      r2,r2,#0x110

r1=0x40,r2=0x150

    0x00029e60:    e584201c    . ..    STR      r2,[r4,#0x1c]    0x00029e64:    e5841018    ....    STR      r1,[r4,#0x18]    0x00029e68:    e3a00001    ....    MOV      r0,#1    0x00029e6c:    e5840010    ....    STR      r0,[r4,#0x10]    0x00029e70:    e8bd4013    .@..    LDMFD    r13!,{r0,r1,r4,r14}    0x00029e74:    e5840014    ....    STR      r0,[r4,#0x14]    0x00029e78:    e1a01000    ....    MOV      r1,r0    0x00029e7c:    e1a0f00e    ....    MOV      pc,r14

向内存中写入一些数据,返回调用。

2.函数Ven ATL $__rt_lib_init

$Ven$AT$L$$__rt_lib_init    0x00029f90:    e59fc000    ....    LDR      r12,0x29f98    0x00029f94:    e12fff1c    ../.    BX       r12$d$f    0x00029f98:    00029d35    5...    DCD    171317

r12=0x29d35,bx命令为条件跳转,如果最低位为0则按照arm指令继续执行跳转位置指令,如果最低位为1则按照THUMBS指令集执行。

__rt_lib_init.text    0x00029d34:    b5f0        ..      PUSH     {r4-r7,r14}    0x00029d36:    1c04        ..      MOV      r4,r0    0x00029d38:    1c0d        ..      MOV      r5,r1    0x00029d3a:    b083        ..      SUB      r13,#0xc$b    0x00029d3c:    f000f934    ..4.    BL       __16_fp_init  ; 0x29fa8

注意THUMBS指令集的命令比ARM的指令集要短。
将r4-r7,r14入栈,改变r4,r5,r13的值,调用__16_fp_init

__16_fp_init$tx$fpl$fpinit    0x00029fa8:    4778        xG      BX       pc$d    0x00029faa:    0000        ..      DCW    0_fp_init$a    0x00029fac:    e92d4010    .@-.    STMFD    r13!,{r4,r14}    0x00029fb0:    ebfffff1    ....    BL       __rt_fp_status_addr  ; 0x29f7c

此时pc指向下一个命令,BX调用则切换回ARM指令集,DCW为分配一段内存空间,这里分配了0个字节,可以认为是用来凑数的,为了使命令对齐。下面将r4,r14入栈,跳转到__rt_fp_status_addr

__rt_fp_status_addr$a    0x00029f7c:    e92d4010    .@-.    STMFD    r13!,{r4,r14}    0x00029f80:    ebffffe4    ....    BL       __user_libspace  ; 0x29f18    0x00029f84:    e2800004    ....    ADD      r0,r0,#4    0x00029f88:    e8bd4010    .@..    LDMFD    r13!,{r4,r14}    0x00029f8c:    e12fff1e    ../.    BX       r14

将r4,r14入栈,跳转到__user_libspace,前面已经说过了,此函数功能很简单,就是把0x40003000放入r0后返回。此后r0=r0+4=0x40003004,取出r4,r14,返回__16_fp_init。

    0x00029fb4:    e3a01000    ....    MOV      r1,#0    0x00029fb8:    e5801000    ....    STR      r1,[r0,#0]__fplib_config_pureend_doubles    0x00029fbc:    e8bd4010    .@..    LDMFD    r13!,{r4,r14}    0x00029fc0:    e12fff1e    ../.    BX       r14

r1=0, 0x40003004=r1=0,r4,r14出栈,返回__rt_lib_init,注:这里如何切换到THUMB状态的没有查到资料,但肯定是切换回THUMB指令集了。

    0x00029d40:    9400        ..      STR      r4,[r13,#0]    0x00029d42:    9501        ..      STR      r5,[r13,#4]

将r4,r5的值依次放入r13增长的方向的内存

    0x00029d44:    2000        .       MOV      r0,#0$b    0x00029d46:    f000f800    ....    BL       0x29d4a

r0=0,跳转到后面语句

    0x00029d4a:    9002        ..      STR      r0,[r13,#8]    0x00029d4c:    4826        &H      LDR      r0,0x29de8    0x00029d4e:    4669        iF      MOV      r1,r13    0x00029d50:    4478        xD      ADD      r0,pc

把r0放入r13后第8字节开始的4个字节,r0=148,用r1保存r13,r0=r0+pc,此时pc=0x29d52, r0=0x29de6。

$b    0x00029d52:    f000f800    ....    BL       0x29d56    0x00029d56:    1c05        ..      MOV      r5,r0    0x00029d58:    1c0e        ..      MOV      r6,r1    0x00029d5a:    a900        ..      ADD      r1,r13,#0    0x00029d5c:    c903        ..      LDMIA    r1!,{r0,r1}

r5=0x29de6,r6为栈底,0x40003060,r1=r13+0,r0,r1赋值

$b    0x00029d5e:    f000f800    ....    BL       $b  ; 0x29d62$b    0x00029d62:    f000f800    ....    BL       $b  ; 0x29d66$b    0x00029d66:    f000f800    ....    BL       0x29d6a    0x00029d6a:    2100        .!      MOV      r1,#0    0x00029d6c:    2000        .       MOV      r0,#0

r0=r1=0

$b    0x00029d6e:    f000f800    ....    BL       0x29d72    0x00029d72:    1c07        ..      MOV      r7,r0$b    0x00029d74:    f000f8ce    ....    BL       __16__user_libspace  ; 0x29f14

r7=0, 跳转到__16__user_libspace,此处程序可能是向堆内写入数据看看是否能够写入。

__16__user_libspace$t.text    0x00029f14:    4778        xG      BX       pc$d    0x00029f16:    0000        ..      DCW    0__user_libspace$a    0x00029f18:    e59f0000    ....    LDR      r0,0x29f20    0x00029f1c:    e12fff1e    ../.    BX       r14

此处实际上还是执行了__user_libspace,r0等于0x40003000并返回。

    0x00029d78:    1c04        ..      MOV      r4,r0    0x00029d7a:    2100        .!      MOV      r1,#0    0x00029d7c:    6207        .b      STR      r7,[r0,#0x20]    0x00029d7e:    2000        .       MOV      r0,#0$b    0x00029d80:    f000f800    ....    BL       0x29d84    0x00029d84:    1c41        A.      ADD      r1,r0,#1    0x00029d86:    6261        ab      STR      r1,[r4,#0x24]    0x00029d88:    2100        .!      MOV      r1,#0    0x00029d8a:    2000        .       MOV      r0,#0$b    0x00029d8c:    f000f800    ....    BL       0x29d90    0x00029d90:    2100        .!      MOV      r1,#0    0x00029d92:    62a0        .b      STR      r0,[r4,#0x28]    0x00029d94:    2000        .       MOV      r0,#0$b    0x00029d96:    f000f800    ....    BL       0x29d9a    0x00029d9a:    2100        .!      MOV      r1,#0    0x00029d9c:    62e0        .b      STR      r0,[r4,#0x2c]    0x00029d9e:    2000        .       MOV      r0,#0$b    0x00029da0:    f000f800    ....    BL       0x29da4    0x00029da4:    6320         c      STR      r0,[r4,#0x30]$b    0x00029da6:    f000f800    ....    BL       $b  ; 0x29daa$b    0x00029daa:    f000f800    ....    BL       $b  ; 0x29dae$b    0x00029dae:    f000f800    ....    BL       $b  ; 0x29db2$b    0x00029db2:    f000f800    ....    BL       $b  ; 0x29db6$b    0x00029db6:    f000f800    ....    BL       $b  ; 0x29dba$b    0x00029dba:    f000f800    ....    BL       $b  ; 0x29dbe$b    0x00029dbe:    f000f800    ....    BL       $b  ; 0x29dc2$b    0x00029dc2:    f000f800    ....    BL       0x29dc6    0x00029dc6:    1c28        (.      MOV      r0,r5    0x00029dc8:    1c31        1.      MOV      r1,r6    0x00029dca:    b003        ..      ADD      r13,#0xc    0x00029dcc:    bcf0        ..      POP      {r4-r7}    0x00029dce:    bc08        ..      POP      {r3}    0x00029dd0:    4718        .G      BX       r3

仍然是向堆内填写数据,最后将栈底上移12字节,恢复r13,使r4-r7出栈,r3出栈,返回上级调用,注意一开始压栈了r4-r7,r14,因此r3=r14,函数返回。调用此函数的为Ven ATL $__rt_lib_init,而其并没有使用BL调用,因此没有改变R14的值,所以将返回更上级函数__rt_entry

    0x00029cd8:    e59fc01c    ....    LDR      r12,0x29cfcmainaddruse    0x00029cdc:    e08cc00f    ....    ADD      r12,r12,pc    0x00029ce0:    e31c0001    ....    TST      r12,#1    0x00029ce4:    128fe00d    ....    ADDNE    r14,pc,#0xd ; #0x29cf9    0x00029ce8:    01a0e00f    ....    MOVEQ    r14,pc    0x00029cec:    e12fff1c    ../.    BX       r12

r12=0xffffffc4,r12=r12+pc=0x29ca4,下面两句不执行。r14=0x00029cec。跳转到0x29ca4,并按照ARM指令集执行

main$a.text    0x00029ca8:    e59f1018    ....    LDR      r1,0x29cc8    0x00029cac:    e3a00000    ....    MOV      r0,#0    0x00029cb0:    e4c10001    ....    STRB     r0,[r1],#1    0x00029cb4:    e2800001    ....    ADD      r0,r0,#1    0x00029cb8:    e3500010    ..P.    CMP      r0,#0x10    0x00029cbc:    bafffffb    ....    BLT      0x29cb0    0x00029cc0:    e3a00001    ....    MOV      r0,#1    0x00029cc4:    e12fff1e    ../.    BX       r14$d    0x00029cc8:    40004000    .@.@    DCD    1073758208_main_redirection$t.text    0x00029ccc:    4770        pG      BX       r14_main    0x00029cce:    4770        pG      BX       r14

看起来这就是主程序了,r1=0x40004000,r0=0,把r0赋值给r1指向的位置,r1=r1+1,r0=r0+1,如果r0!=16则继续进行赋值循环。此后将r0设为1,应当是作为返回值了,此处可以看出来主程序上来就完成了c语言代码的子程序的功能,是因为设置了编译时按照空间优先,所以编译器自动把代码优化了。
BX r14因为r14的值一直没有受到影响,因此按照调用的时候的值0x00029cec返回。

    0x00029cf0:    e28fc001    ....    ADD      r12,pc,#1 ; #0x29cf9    0x00029cf4:    e12fff1c    ../.    BX       r12

下面跳转到THUMB指令集继续运行(PC指的就是目前位置)。

thumbmainreturn$b$t    0x00029cf8:    f000f812    ....    BL       exit  ; 0x29d20

调用THUMB的exit

exit$t.text    0x00029d20:    b510        ..      PUSH     {r4,r14}    0x00029d22:    1c04        ..      MOV      r4,r0$b    0x00029d24:    f000f800    ....    BL       0x29d28    0x00029d28:    1c20         .      MOV      r0,r4$b    0x00029d2a:    f7ffffe9    ....    BL       __rt_exit  ; 0x29d00

把r4,r14入栈,r4=r0,r0=r4,调用__rt_exit。

__rt_exit$t    0x00029d00:    4778        xG      BX       pc$d    0x00029d02:    0000        ..      DCW    0__32__rt_exit$a    0x00029d04:    e92d4001    .@-.    STMFD    r13!,{r0,r14}    0x00029d08:    eb0000a3    ....    BL       $Ven$AT$L$$__rt_lib_shutdown  ; 0x29f9c

首先将THUMB切换回ARM,使r0(返回值),r14入栈,跳转到Ven ATL $__rt_lib_shutdown

$Ven$AT$L$$__rt_lib_shutdown$a    0x00029f9c:    e59fc000    ....    LDR      r12,0x29fa4    0x00029fa0:    e12fff1c    ../.    BX       r12$d$f    0x00029fa4:    00029dd3    ....    DCD    171475

此段代码的目的是切换到THUMB指令集并跳转到0x00029dd2运行。

__rt_lib_shutdown    0x00029dd2:    b508        ..      PUSH     {r3,r14}$b    0x00029dd4:    f000f800    ....    BL       $b  ; 0x29dd8$b    0x00029dd8:    f000f800    ....    BL       $b  ; 0x29ddc$b    0x00029ddc:    f000f800    ....    BL       0x29de0    0x00029de0:    b001        ..      ADD      r13,#4    0x00029de2:    bc08        ..      POP      {r3}    0x00029de4:    4718        .G      BX       r3

此处没有进行任何实际操作,返回__rt_exit

    0x00029d0c:    e8bd4001    .@..    LDMFD    r13!,{r0,r14}    0x00029d10:    ea000001    ....    B        __rt_abort1  ; 0x29d1c__rt_abort$t    0x00029d14:    4778        xG      BX       pc$d    0x00029d16:    0000        ..      DCW    0__32__rt_abort$a    0x00029d18:    e3e00000    ....    MVN      r0,#0__rt_abort1    0x00029d1c:    ea000076    v...    B        _sys_exit  ; 0x29efc

使r0,r14出栈,跳转到__rt_abort1,再跳转到_sys_exit。

_sys_exit$a    0x00029efc:    e3a00018    ....    MOV      r0,#0x18    0x00029f00:    e59f1008    ....    LDR      r1,0x29f10    0x00029f04:    ef123456    V4..    SWI      0x123456    0x00029f08:    e12fff1e    ../.    BX       r14$d$f    0x00029f0c:    00000065    e...    DCD    101    0x00029f10:    00020026    &...    DCD    131110

调用了软中断,之后返回上级调用exit

    0x00029d2e:    bc10        ..      POP      {r4}    0x00029d30:    bc08        ..      POP      {r3}    0x00029d32:    4718        .G      BX       r3

走到这里基本上就等于释放了资源退出了,由于并没有分配任何资源因此退出代码没有什么实质操作。

附录.汇编代码

    ROM地址       汇编二进制码          汇编指令__main$a!!!    0x00029c00:    e28f8090    ....    ADD      r8,pc,#0x90 ; #0x29c98    0x00029c04:    e898000f    ....    LDMIA    r8,{r0-r3}    0x00029c08:    e0800008    ....    ADD      r0,r0,r8    0x00029c0c:    e0811008    ....    ADD      r1,r1,r8    0x00029c10:    e0822008    . ..    ADD      r2,r2,r8    0x00029c14:    e0833008    .0..    ADD      r3,r3,r8    0x00029c18:    e240b001    ..@.    SUB      r11,r0,#1    0x00029c1c:    e242c001    ..B.    SUB      r12,r2,#1_move_region    0x00029c20:    e1500001    ..P.    CMP      r0,r1    0x00029c24:    0a00000e    ....    BEQ      _zero_region  ; 0x29c64    0x00029c28:    e8b00070    p...    LDMIA    r0!,{r4-r6}    0x00029c2c:    e1540005    ..T.    CMP      r4,r5    0x00029c30:    0afffffa    ....    BEQ      _move_region  ; 0x29c20    0x00029c34:    e3140001    ....    TST      r4,#1    0x00029c38:    1084400b    .@..    ADDNE    r4,r4,r11    0x00029c3c:    e3150001    ....    TST      r5,#1    0x00029c40:    1085500b    .P..    ADDNE    r5,r5,r11    0x00029c44:    e3150002    ....    TST      r5,#2    0x00029c48:    10855009    .P..    ADDNE    r5,r5,r9    0x00029c4c:    e3c55003    .P..    BIC      r5,r5,#3_move_loop    0x00029c50:    e2566004    .`V.    SUBS     r6,r6,#4    0x00029c54:    24947004    .p.$    LDRCS    r7,[r4],#4    0x00029c58:    24857004    .p.$    STRCS    r7,[r5],#4    0x00029c5c:    8afffffb    ....    BHI      _move_loop  ; 0x29c50    0x00029c60:    eaffffee    ....    B        _move_region  ; 0x29c20_zero_region    0x00029c64:    e1520003    ..R.    CMP      r2,r3    0x00029c68:    0b000018    ....    BLEQ     __rt_entry  ; 0x29cd0    0x00029c6c:    e3a07000    .p..    MOV      r7,#0    0x00029c70:    e8b20030    0...    LDMIA    r2!,{r4,r5}    0x00029c74:    e3140001    ....    TST      r4,#1    0x00029c78:    1084400c    .@..    ADDNE    r4,r4,r12    0x00029c7c:    e3140002    ....    TST      r4,#2    0x00029c80:    10844009    .@..    ADDNE    r4,r4,r9    0x00029c84:    e3c44003    .@..    BIC      r4,r4,#3_zero_loop    0x00029c88:    e2555004    .PU.    SUBS     r5,r5,#4    0x00029c8c:    24847004    .p.$    STRCS    r7,[r4],#4    0x00029c90:    8afffffc    ....    BHI      _zero_loop  ; 0x29c88    0x00029c94:    eafffff2    ....    B        _zero_region  ; 0x29c64_region_table$d    0x00029c98:    0000032c    ,...    DCD    812    0x00029c9c:    00000350    P...    DCD    848    0x00029ca0:    00000350    P...    DCD    848    0x00029ca4:    00000368    h...    DCD    872main$a.text    0x00029ca8:    e59f1018    ....    LDR      r1,0x29cc8    0x00029cac:    e3a00000    ....    MOV      r0,#0    0x00029cb0:    e4c10001    ....    STRB     r0,[r1],#1    0x00029cb4:    e2800001    ....    ADD      r0,r0,#1    0x00029cb8:    e3500010    ..P.    CMP      r0,#0x10    0x00029cbc:    bafffffb    ....    BLT      0x29cb0    0x00029cc0:    e3a00001    ....    MOV      r0,#1    0x00029cc4:    e12fff1e    ../.    BX       r14$d    0x00029cc8:    40004000    .@.@    DCD    1073758208_main_redirection$t.text    0x00029ccc:    4770        pG      BX       r14_main    0x00029cce:    4770        pG      BX       r14__rt_entry$a.text    0x00029cd0:    eb000046    F...    BL       __rt_stackheap_init  ; 0x29df0    0x00029cd4:    eb0000ad    ....    BL       $Ven$AT$L$$__rt_lib_init  ; 0x29f90    0x00029cd8:    e59fc01c    ....    LDR      r12,0x29cfcmainaddruse    0x00029cdc:    e08cc00f    ....    ADD      r12,r12,pc    0x00029ce0:    e31c0001    ....    TST      r12,#1    0x00029ce4:    128fe00d    ....    ADDNE    r14,pc,#0xd ; #0x29cf9    0x00029ce8:    01a0e00f    ....    MOVEQ    r14,pc    0x00029cec:    e12fff1c    ../.    BX       r12    0x00029cf0:    e28fc001    ....    ADD      r12,pc,#1 ; #0x29cf9    0x00029cf4:    e12fff1c    ../.    BX       r12thumbmainreturn$b$t    0x00029cf8:    f000f812    ....    BL       exit  ; 0x29d20mainaddr$d$f    0x00029cfc:    ffffffc4    ....    DCD    4294967236__rt_exit$t    0x00029d00:    4778        xG      BX       pc$d    0x00029d02:    0000        ..      DCW    0__32__rt_exit$a    0x00029d04:    e92d4001    .@-.    STMFD    r13!,{r0,r14}    0x00029d08:    eb0000a3    ....    BL       $Ven$AT$L$$__rt_lib_shutdown  ; 0x29f9c    0x00029d0c:    e8bd4001    .@..    LDMFD    r13!,{r0,r14}    0x00029d10:    ea000001    ....    B        __rt_abort1  ; 0x29d1c__rt_abort$t    0x00029d14:    4778        xG      BX       pc$d    0x00029d16:    0000        ..      DCW    0__32__rt_abort$a    0x00029d18:    e3e00000    ....    MVN      r0,#0__rt_abort1    0x00029d1c:    ea000076    v...    B        _sys_exit  ; 0x29efcexit$t.text    0x00029d20:    b510        ..      PUSH     {r4,r14}    0x00029d22:    1c04        ..      MOV      r4,r0$b    0x00029d24:    f000f800    ....    BL       0x29d28    0x00029d28:    1c20         .      MOV      r0,r4$b    0x00029d2a:    f7ffffe9    ....    BL       __rt_exit  ; 0x29d00    0x00029d2e:    bc10        ..      POP      {r4}    0x00029d30:    bc08        ..      POP      {r3}    0x00029d32:    4718        .G      BX       r3__rt_lib_init.text    0x00029d34:    b5f0        ..      PUSH     {r4-r7,r14}    0x00029d36:    1c04        ..      MOV      r4,r0    0x00029d38:    1c0d        ..      MOV      r5,r1    0x00029d3a:    b083        ..      SUB      r13,#0xc$b    0x00029d3c:    f000f934    ..4.    BL       __16_fp_init  ; 0x29fa8    0x00029d40:    9400        ..      STR      r4,[r13,#0]    0x00029d42:    9501        ..      STR      r5,[r13,#4]    0x00029d44:    2000        .       MOV      r0,#0$b    0x00029d46:    f000f800    ....    BL       0x29d4a    0x00029d4a:    9002        ..      STR      r0,[r13,#8]    0x00029d4c:    4826        &H      LDR      r0,0x29de8    0x00029d4e:    4669        iF      MOV      r1,r13    0x00029d50:    4478        xD      ADD      r0,pc$b    0x00029d52:    f000f800    ....    BL       0x29d56    0x00029d56:    1c05        ..      MOV      r5,r0    0x00029d58:    1c0e        ..      MOV      r6,r1    0x00029d5a:    a900        ..      ADD      r1,r13,#0    0x00029d5c:    c903        ..      LDMIA    r1!,{r0,r1}$b    0x00029d5e:    f000f800    ....    BL       $b  ; 0x29d62$b    0x00029d62:    f000f800    ....    BL       $b  ; 0x29d66$b    0x00029d66:    f000f800    ....    BL       0x29d6a    0x00029d6a:    2100        .!      MOV      r1,#0    0x00029d6c:    2000        .       MOV      r0,#0$b    0x00029d6e:    f000f800    ....    BL       0x29d72    0x00029d72:    1c07        ..      MOV      r7,r0$b    0x00029d74:    f000f8ce    ....    BL       __16__user_libspace  ; 0x29f14    0x00029d78:    1c04        ..      MOV      r4,r0    0x00029d7a:    2100        .!      MOV      r1,#0    0x00029d7c:    6207        .b      STR      r7,[r0,#0x20]    0x00029d7e:    2000        .       MOV      r0,#0$b    0x00029d80:    f000f800    ....    BL       0x29d84    0x00029d84:    1c41        A.      ADD      r1,r0,#1    0x00029d86:    6261        ab      STR      r1,[r4,#0x24]    0x00029d88:    2100        .!      MOV      r1,#0    0x00029d8a:    2000        .       MOV      r0,#0$b    0x00029d8c:    f000f800    ....    BL       0x29d90    0x00029d90:    2100        .!      MOV      r1,#0    0x00029d92:    62a0        .b      STR      r0,[r4,#0x28]    0x00029d94:    2000        .       MOV      r0,#0$b    0x00029d96:    f000f800    ....    BL       0x29d9a    0x00029d9a:    2100        .!      MOV      r1,#0    0x00029d9c:    62e0        .b      STR      r0,[r4,#0x2c]    0x00029d9e:    2000        .       MOV      r0,#0$b    0x00029da0:    f000f800    ....    BL       0x29da4    0x00029da4:    6320         c      STR      r0,[r4,#0x30]$b    0x00029da6:    f000f800    ....    BL       $b  ; 0x29daa$b    0x00029daa:    f000f800    ....    BL       $b  ; 0x29dae$b    0x00029dae:    f000f800    ....    BL       $b  ; 0x29db2$b    0x00029db2:    f000f800    ....    BL       $b  ; 0x29db6$b    0x00029db6:    f000f800    ....    BL       $b  ; 0x29dba$b    0x00029dba:    f000f800    ....    BL       $b  ; 0x29dbe$b    0x00029dbe:    f000f800    ....    BL       $b  ; 0x29dc2$b    0x00029dc2:    f000f800    ....    BL       0x29dc6    0x00029dc6:    1c28        (.      MOV      r0,r5    0x00029dc8:    1c31        1.      MOV      r1,r6    0x00029dca:    b003        ..      ADD      r13,#0xc    0x00029dcc:    bcf0        ..      POP      {r4-r7}    0x00029dce:    bc08        ..      POP      {r3}    0x00029dd0:    4718        .G      BX       r3__rt_lib_shutdown    0x00029dd2:    b508        ..      PUSH     {r3,r14}$b    0x00029dd4:    f000f800    ....    BL       $b  ; 0x29dd8$b    0x00029dd8:    f000f800    ....    BL       $b  ; 0x29ddc$b    0x00029ddc:    f000f800    ....    BL       0x29de0    0x00029de0:    b001        ..      ADD      r13,#4    0x00029de2:    bc08        ..      POP      {r3}    0x00029de4:    4718        .G      BX       r3$d    0x00029de6:    0000        ..      DCW    0    0x00029de8:    00000094    ....    DCD    148__16__rt_stackheap_init$t.text    0x00029dec:    4778        xG      BX       pc$d    0x00029dee:    0000        ..      DCW    0__rt_stackheap_init$a    0x00029df0:    e1a0500e    .P..    MOV      r5,r14    0x00029df4:    eb000047    G...    BL       __user_libspace  ; 0x29f18    0x00029df8:    e1a0e005    ....    MOV      r14,r5    0x00029dfc:    e1a04000    .@..    MOV      r4,r0    0x00029e00:    e1a0100d    ....    MOV      r1,r13    0x00029e04:    e1a0300a    .0..    MOV      r3,r10    0x00029e08:    e3c00007    ....    BIC      r0,r0,#7    0x00029e0c:    e280d060    `...    ADD      r13,r0,#0x60    0x00029e10:    e92d4010    .@-.    STMFD    r13!,{r4,r14}    0x00029e14:    eb000043    C...    BL       __user_initial_stackheap  ; 0x29f28    0x00029e18:    e8bd4010    .@..    LDMFD    r13!,{r4,r14}    0x00029e1c:    e3c1d007    ....    BIC      r13,r1,#7    0x00029e20:    e3a06000    .`..    MOV      r6,#0    0x00029e24:    e3a07000    .p..    MOV      r7,#0    0x00029e28:    e3a08000    ....    MOV      r8,#0    0x00029e2c:    e3a0b000    ....    MOV      r11,#0    0x00029e30:    e1a0c004    ....    MOV      r12,r4    0x00029e34:    e8ac09c0    ....    STMIA    r12!,{r6-r8,r11}    0x00029e38:    e8ac09c0    ....    STMIA    r12!,{r6-r8,r11}    0x00029e3c:    e8ac09c0    ....    STMIA    r12!,{r6-r8,r11}    0x00029e40:    e8ac09c0    ....    STMIA    r12!,{r6-r8,r11}    0x00029e44:    e92d4013    .@-.    STMFD    r13!,{r0,r1,r4,r14}    0x00029e48:    e3a00000    ....    MOV      r0,#0    0x00029e4c:    e3a01000    ....    MOV      r1,#0    0x00029e50:    ebffffff    ....    BL       0x29e54    0x00029e54:    e2811040    @...    ADD      r1,r1,#0x40    0x00029e58:    e0802001    . ..    ADD      r2,r0,r1    0x00029e5c:    e2822f44    D/..    ADD      r2,r2,#0x110    0x00029e60:    e584201c    . ..    STR      r2,[r4,#0x1c]    0x00029e64:    e5841018    ....    STR      r1,[r4,#0x18]    0x00029e68:    e3a00001    ....    MOV      r0,#1    0x00029e6c:    e5840010    ....    STR      r0,[r4,#0x10]    0x00029e70:    e8bd4013    .@..    LDMFD    r13!,{r0,r1,r4,r14}    0x00029e74:    e5840014    ....    STR      r0,[r4,#0x14]    0x00029e78:    e1a01000    ....    MOV      r1,r0    0x00029e7c:    e1a0f00e    ....    MOV      pc,r14__16__rt_heap_extend$t    0x00029e80:    4778        xG      BX       pc$d    0x00029e82:    0000        ..      DCW    0__rt_heap_extend$a    0x00029e84:    e92d4010    .@-.    STMFD    r13!,{r4,r14}    0x00029e88:    e92d0003    ..-.    STMFD    r13!,{r0,r1}    0x00029e8c:    eb000021    !...    BL       __user_libspace  ; 0x29f18    0x00029e90:    e1a04000    .@..    MOV      r4,r0    0x00029e94:    e8bd0003    ....    LDMFD    r13!,{r0,r1}    0x00029e98:    e594301c    .0..    LDR      r3,[r4,#0x1c]    0x00029e9c:    e04d3003    .0M.    SUB      r3,r13,r3    0x00029ea0:    e5942014    . ..    LDR      r2,[r4,#0x14]    0x00029ea4:    e5812000    . ..    STR      r2,[r1,#0]    0x00029ea8:    e082e000    ....    ADD      r14,r2,r0    0x00029eac:    e15e0003    ..^.    CMP      r14,r3    0x00029eb0:    8a00000b    ....    BHI      _heap_overflow  ; 0x29ee4    0x00029eb4:    e093300e    .0..    ADDS     r3,r3,r14    0x00029eb8:    e1a03063    c0..    MOV      r3,r3,RRX    0x00029ebc:    e3c33007    .0..    BIC      r3,r3,#7    0x00029ec0:    e28e1d40    @...    ADD      r1,r14,#0x1000    0x00029ec4:    e2811007    ....    ADD      r1,r1,#7    0x00029ec8:    e3c11007    ....    BIC      r1,r1,#7    0x00029ecc:    e1510003    ..Q.    CMP      r1,r3    0x00029ed0:    81a01003    ....    MOVHI    r1,r3    0x00029ed4:    e0410002    ..A.    SUB      r0,r1,r2    0x00029ed8:    e5841014    ....    STR      r1,[r4,#0x14]    0x00029edc:    e8bd4010    .@..    LDMFD    r13!,{r4,r14}    0x00029ee0:    e12fff1e    ../.    BX       r14_heap_overflow    0x00029ee4:    e1a02000    . ..    MOV      r2,r0    0x00029ee8:    e3a00000    ....    MOV      r0,#0    0x00029eec:    ebffffff    ....    BL       0x29ef0    0x00029ef0:    e8bd4010    .@..    LDMFD    r13!,{r4,r14}    0x00029ef4:    e12fff1e    ../.    BX       r14__16_sys_exit$t.text    0x00029ef8:    4778        xG      BX       pc$d    0x00029efa:    0000        ..      DCW    0_sys_exit$a    0x00029efc:    e3a00018    ....    MOV      r0,#0x18    0x00029f00:    e59f1008    ....    LDR      r1,0x29f10    0x00029f04:    ef123456    V4..    SWI      0x123456    0x00029f08:    e12fff1e    ../.    BX       r14$d$f    0x00029f0c:    00000065    e...    DCD    101    0x00029f10:    00020026    &...    DCD    131110__16__user_libspace$t.text    0x00029f14:    4778        xG      BX       pc$d    0x00029f16:    0000        ..      DCW    0__user_libspace$a    0x00029f18:    e59f0000    ....    LDR      r0,0x29f20    0x00029f1c:    e12fff1e    ../.    BX       r14$d    0x00029f20:    40003000    .0.@    DCD    1073754112__16__user_initial_stackheap$t.text    0x00029f24:    4778        xG      BX       pc$d    0x00029f26:    0000        ..      DCW    0__user_initial_stackheap$a    0x00029f28:    e92d4000    .@-.    STMFD    r13!,{r14}    0x00029f2c:    e24dd014    ..M.    SUB      r13,r13,#0x14    0x00029f30:    e1a0100d    ....    MOV      r1,r13    0x00029f34:    e28d2004    . ..    ADD      r2,r13,#4    0x00029f38:    e5812000    . ..    STR      r2,[r1,#0]    0x00029f3c:    e3a00016    ....    MOV      r0,#0x16    0x00029f40:    ef123456    V4..    SWI      0x123456    0x00029f44:    e59d0004    ....    LDR      r0,[r13,#4]    0x00029f48:    e59d100c    ....    LDR      r1,[r13,#0xc]    0x00029f4c:    e59d2008    . ..    LDR      r2,[r13,#8]    0x00029f50:    e59d3010    .0..    LDR      r3,[r13,#0x10]    0x00029f54:    e3500000    ..P.    CMP      r0,#0    0x00029f58:    059f000c    ....    LDREQ    r0,0x29f6c    0x00029f5c:    e28dd014    ....    ADD      r13,r13,#0x14    0x00029f60:    e8bd4000    .@..    LDMFD    r13!,{r14}    0x00029f64:    e12fff1e    ../.    BX       r14$d$f    0x00029f68:    00000009    ....    DCD    9_RW_Limit    0x00029f6c:    40003060    `0.@    DCD    1073754208__I_use_semihosting_swi__semihosting_swi_guard$t.text    0x00029f70:    4778        xG      BX       pc$d    0x00029f72:    0000        ..      DCW    0__32__I_use_semihosting_swi$a    0x00029f74:    e12fff1e    ../.    BX       r14__16__rt_fp_status_addr$t.text    0x00029f78:    4778        xG      BX       pc$d    0x00029f7a:    0000        ..      DCW    0__rt_fp_status_addr$a    0x00029f7c:    e92d4010    .@-.    STMFD    r13!,{r4,r14}    0x00029f80:    ebffffe4    ....    BL       __user_libspace  ; 0x29f18    0x00029f84:    e2800004    ....    ADD      r0,r0,#4    0x00029f88:    e8bd4010    .@..    LDMFD    r13!,{r4,r14}    0x00029f8c:    e12fff1e    ../.    BX       r14$Ven$AT$L$$__rt_lib_init    0x00029f90:    e59fc000    ....    LDR      r12,0x29f98    0x00029f94:    e12fff1c    ../.    BX       r12$d$f    0x00029f98:    00029d35    5...    DCD    171317$Ven$AT$L$$__rt_lib_shutdown$a    0x00029f9c:    e59fc000    ....    LDR      r12,0x29fa4    0x00029fa0:    e12fff1c    ../.    BX       r12$d$f    0x00029fa4:    00029dd3    ....    DCD    171475__16_fp_init$tx$fpl$fpinit    0x00029fa8:    4778        xG      BX       pc$d    0x00029faa:    0000        ..      DCW    0_fp_init$a    0x00029fac:    e92d4010    .@-.    STMFD    r13!,{r4,r14}    0x00029fb0:    ebfffff1    ....    BL       __rt_fp_status_addr  ; 0x29f7c    0x00029fb4:    e3a01000    ....    MOV      r1,#0    0x00029fb8:    e5801000    ....    STR      r1,[r0,#0]__fplib_config_pureend_doubles    0x00029fbc:    e8bd4010    .@..    LDMFD    r13!,{r4,r14}    0x00029fc0:    e12fff1e    ../.    BX       r14Region$$Table$$Base$d    0x00029fc4:    00000000    ....    DCD    0    0x00029fc8:    00000000    ....    DCD    0    0x00029fcc:    00000000    ....    DCD    0    0x00029fd0:    0002a000    ....    DCD    172032    0x00029fd4:    40003000    .0.@    DCD    1073754112    0x00029fd8:    00000000    ....    DCD    0    0x00029fdc:    0002a000    ....    DCD    172032    0x00029fe0:    40003000    .0.@    DCD    1073754112    0x00029fe4:    00000000    ....    DCD    0Region$$Table$$LimitZISection$$Table$$Base    0x00029fe8:    0002a000    ....    DCD    172032    0x00029fec:    00000000    ....    DCD    0    0x00029ff0:    40003000    .0.@    DCD    1073754112    0x00029ff4:    00000000    ....    DCD    0    0x00029ff8:    40003000    .0.@    DCD    1073754112    0x00029ffc:    00000060    `...    DCD    96ZISection$$Table$$Limit
0 0
原创粉丝点击