一、简单写个函数test1调用test2,test2调用test3,test3调用test4的 navtive程序,当运行到test4时候,请画出栈布图.
test.c
#include <stdio.h>
void test4()
{
int *p0;
int *p1 = NULL;
*p1 = 0x1122;
}
void test3()
{
int k = 300;
test4();
}
void test2()
{
int j1 = 5;
j1 = j1*j1;
test3();
}
void test1()
{
int i1 = 10;
i1 = i1 +100;
test2();
}
int main( int argc, char **argv)
{
int v0 = 11, v1 = 22;
int v2;
v2 = v0 -v1;
test1();
return 1;
}
Android.mk
LOCAL_PATH:=$(call my-dir)
include $(CLEAR_VARS)
LOCAL_CFLAGS += -g3 -O0 #取消gcc优化
LOCAL_SRC_FILES:=test.c
LOCAL_MODULE:=test
include $(BUILD_EXECUTABLE)
编译出可执行文件test,并使用objdump工具
{
mmm vendor/test;
arm-linux-androideabi-objdump -S out/target/product/$/symbols/system/bin/test >vendor/test/test-arm32.S
}
test-arm32.S
00000398 <test4>:
#include <stdio.h>
void test4()
{
398: b082 sub sp, #8 //sp向低地址偏移#8字节
int *p0; //怎么没看到p0的汇编代码???
int *p1 = NULL;
39a: 2300 movs r3, #0
39c: 9301 str r3, [sp, #4]
*p1 = 0x1122;
39e: 9b01 ldr r3, [sp, #4]
3a0: f241 1222 movw r2, #4386 ; 0x1122
3a4: 601a str r2, [r3, #0] //此处非法内存访问,发生native exception
}
3a6: b002 add sp, #8
3a8: 4770 bx lr
3aa: bf00 nop
000003ac <test3>:
void test3()
{
3ac: b500 push {lr} //test3返回地址入栈
3ae: b083 sub sp, #12 //sp向低地址偏移#12字节
int k = 300;
3b0: f44f 7396 mov.w r3, #300 ; 0x12c
3b4: 9301 str r3, [sp, #4]
test4();
3b6: f7ff ffef bl 398 <test4>
}
3ba: b003 add sp, #12
3bc: f85d fb04 ldr.w pc, [sp], #4
000003c0 <test2>:
void test2()
{
3c0: b500 push {lr} //test2返回地址入栈
3c2: b083 sub sp, #12 //sp向低地址偏移#12字节
int j1 = 5;
3c4: 2305 movs r3, #5
3c6: 9301 str r3, [sp, #4]
j1 = j1*j1;
3c8: 9b01 ldr r3, [sp, #4]
3ca: 9a01 ldr r2, [sp, #4]
3cc: fb02 f303 mul.w r3, r2, r3
3d0: 9301 str r3, [sp, #4]
test3();
3d2: f7ff ffeb bl 3ac <test3>
}
3d6: b003 add sp, #12
3d8: f85d fb04 ldr.w pc, [sp], #4
000003dc <test1>:
void test1()
{
3dc: b500 push {lr} //test1返回地址入栈
3de: b083 sub sp, #12 //sp向低地址偏移#12字节
int i1 = 10;
3e0: 230a movs r3, #10 //局部变量入栈
3e2: 9301 str r3, [sp, #4]
i1 = i1 +100;
3e4: 9b01 ldr r3, [sp, #4]
3e6: 3364 adds r3, #100 ; 0x64
3e8: 9301 str r3, [sp, #4]
test2();
3ea: f7ff ffe9 bl 3c0 <test2>
}
3ee: b003 add sp, #12
3f0: f85d fb04 ldr.w pc, [sp], #4
000003f4 <main>:
int main( int argc, char **argv)
{
3f4: b500 push {lr} //main返回地址压入栈,sp向下移动#4字节
3f6: b087 sub sp, #28 //sp向低地址偏移#28字节
3f8: 9001 str r0, [sp, #4]
3fa: 9100 str r1, [sp, #0]
int v0 = 11, v1 = 22;
3fc: 230b movs r3, #11
3fe: 9303 str r3, [sp, #12]
400: 2316 movs r3, #22
402: 9304 str r3, [sp, #16]
int v2;
v2 = v0 -v1;
404: 9a03 ldr r2, [sp, #12]
406: 9b04 ldr r3, [sp, #16]
408: 1ad3 subs r3, r2, r3
40a: 9305 str r3, [sp, #20]
test1();
40c: f7ff ffe6 bl 3dc <test1>
return 1;
410: 2301 movs r3, #1
}
412: 4618 mov r0, r3
414: b007 add sp, #28
416: f85d fb04 ldr.w pc, [sp], #4
41a: bf00 nop
栈布图
发生NE时的调用栈和各寄存器情况:
(gdb) bt
#0 0xb6f113a4 in test4 () at vendor/test/test.c:8
#1 0xb6f113ba in test3 () at vendor/test/test.c:15
#2 0xb6f113d6 in test2 () at vendor/test/test.c:24
#3 0xb6f113ee in test1 () at vendor/test/test.c:33
#4 0xb6f11410 in main (argc=1, argv=0xbe9bba54) at vendor/test/test.c:43
0xb6f9a39e <test4+6>: 01 9b ldr r3, [sp, #4]
0xb6f9a3a0 <test4+8>: 41 f2 22 12 movw r2, #4386 ; 0x1122
=> 0xb6f9a3a4 <test4+12>: 1a 60 str r2, [r3, #0]
(gdb) info reg
r0 0x1 1
r1 0xbec38a54 3200485972
r2 0x1122 4386
r3 0x0 0
r4 0xbec38a54 3200485972
r5 0x1 1
r6 0xbec38a5c 3200485980
r7 0xb6f9a3f5 3069813749
r8 0x0 0
r9 0x0 0
r10 0x0 0
r11 0xbec38a34 3200485940
r12 0xb6f73638 3069654584
sp 0xbec389c8 0xbec389c8
lr 0xb6f9a3bb -1225153605
pc 0xb6f9a3a4 0xb6f9a3a4 <test4+12>
cpsr 0x40070030 1074200624