我正在尝试为arm bear metal编译代码构建二进制翻译器,并尝试通过将其与qemu-arm进行比较来验证正确的执行流程.我使用以下命令来转储程序流:
qemu-arm -d in_asm,cpu -singlestep -D a.flow a.out
我注意到一些奇怪的东西,程序似乎跳转到一个无关的指令,因为0x000080b4不是分支,也不是0x000093ec之后的下一条指令.
0x000093ec: 1afffff9 bne 0x93d8
R00=00000000 R01=00009c44 R02=00000002 R03=00000000
R04=00000001 R05=0001d028 R06=00000002 R07=00000000
R08=00000000 R09=00000000 R10=0001d024 R11=00000000
R12=f6ffed88 R13=f6ffed88 R14=000093e8 R15=000093ec
PSR=20000010 --C- A usr32
R00=00000000 R01=00009c44 R02=00000002 R03=00000000
R04=00000001 R05=0001d028 R06=00000002 R07=00000000
R08=00000000 R09=00000000 R10=0001d024 R11=00000000
R12=f6ffed88 R13=f6ffed88 R14=000093e8 R15=000093d8
PSR=20000010 --C- A usr32
----------------
IN:
0x000080b4: e59f3060 ldr r3, [pc, #96] ; 0x811c
Run Code Online (Sandbox Code Playgroud)
实际执行的指令对应<frame_dummy>于反汇编中标记的开始.有人可以解释模拟器中实际发生了什么,这种行为在ARM架构中是否正常?该计划编制为:arm-none-eabi-gcc --specs=rdimon.specs a.c
这是没有CPU状态的程序流的相同部分:
0x0000804c: e59f3018 ldr r3, [pc, #24] ; 0x806c
0x00008050: e3530000 cmp r3, #0 ; 0x0
0x00008054: 01a0f00e moveq pc, lr
----------------
IN: __libc_init_array
0x000093e8: e1560004 cmp r6, r4
0x000093ec: 1afffff9 bne 0x93d8
----------------
IN:
0x000080b4: e59f3060 ldr r3, [pc, #96] ; 0x811c
0x000080b8: e3530000 cmp r3, #0 ; 0x0
0x000080bc: 0a000009 beq 0x80e8
Run Code Online (Sandbox Code Playgroud)
这是这部分的反汇编:
93d4: 0a000005 beq 93f0 <__libc_init_array+0x68>
93d8: e2844001 add r4, r4, #1
93dc: e4953004 ldr r3, [r5], #4
93e0: e1a0e00f mov lr, pc
93e4: e1a0f003 mov pc, r3
93e8: e1560004 cmp r6, r4
93ec: 1afffff9 bne 93d8 <__libc_init_array+0x50>
93f0: e8bd4070 pop {r4, r5, r6, lr}
Run Code Online (Sandbox Code Playgroud)
这是先前发出的TB的反向跳转,你甚至不需要阅读那么多:
IN: __libc_init_array
0x000093d8: e2844001 add r4, r4, #1 ; 0x1
0x000093dc: e4953004 ldr r3, [r5], #4
0x000093e0: e1a0e00f mov lr, pc
0x000093e4: e1a0f003 mov pc, r3
----------------
IN: register_fini
0x0000804c: e59f3018 ldr r3, [pc, #24] ; 0x806c
0x00008050: e3530000 cmp r3, #0 ; 0x0
0x00008054: 01a0f00e moveq pc, lr
----------------
IN: __libc_init_array
0x000093e8: e1560004 cmp r6, r4
0x000093ec: 1afffff9 bne 0x93d8
Run Code Online (Sandbox Code Playgroud)
所以,qemu没有再显示它.注意这个循环是迭代函数指针,第一个指向,register_fini第二个指向有0x000080b4问题的神奇地址(没有符号).当这个未命名的函数有条件地返回并且moveq pc, lr控制权被转移回__libc_init_array地址0x000093e8,然后该地址确定已到达数组结束并再次返回其调用者处0x000093f0.