2016-09-20 70 views
1

我有以下代码:大会,全局变量

const ClassTwo g_classTwo; 

void ClassOne::first() 
{ 
    g_classTwo.doSomething(1); 
} 

void ClassOne::second() 
{ 
    g_classTwo.doSomething(2); 
} 

将会产生以下objdump的:

void ClassOne::first() 
{ 
1089c50: e1a0c00d mov ip, sp 
1089c54: e92dd800 push {fp, ip, lr, pc} 
1089c58: e24cb004 sub fp, ip, #4 
1089c5c: e24dd008 sub sp, sp, #8 
1089c60: e50b0010 str r0, [fp, #-16] 
    g_classTwo.doSomething(1); 
1089c64: e59f3014 ldr r3, [pc, #20] ; 1089c80 <ClassOne::first()+0x30> 
1089c68: e08f3003 add r3, pc, r3 
1089c6c: e1a00003 mov r0, r3 
1089c70: e3a01001 mov r1, #1 
1089c74: ebffffe2 bl 1089c04 <ClassTwo::doSomething(int) const> 
} 
1089c78: e24bd00c sub sp, fp, #12 
1089c7c: e89da800 ldm sp, {fp, sp, pc} 
1089c80: 060cd35c .word 0x060cd35c 

01089c84 <ClassOne::second()>: 

void ClassOne::second() 
{ 
1089c84: e1a0c00d mov ip, sp 
1089c88: e92dd800 push {fp, ip, lr, pc} 
1089c8c: e24cb004 sub fp, ip, #4 
1089c90: e24dd008 sub sp, sp, #8 
1089c94: e50b0010 str r0, [fp, #-16] 
    g_classTwo.doSomething(2); 
1089c98: e59f3014 ldr r3, [pc, #20] ; 1089cb4 <ClassOne::second()+0x30> 
1089c9c: e08f3003 add r3, pc, r3 
1089ca0: e1a00003 mov r0, r3 
1089ca4: e3a01002 mov r1, #2 
1089ca8: ebffffd5 bl 1089c04 <ClassTwo::doSomething(int) const> 
} 
1089cac: e24bd00c sub sp, fp, #12 
1089cb0: e89da800 ldm sp, {fp, sp, pc} 
1089cb4: 060cd328 .word 0x060cd328 

两种方法加载的g_classTwo与PC机相对于偏移地址:ldr r3, [pc, #20],对于第一种和第二种方法分别转化为0x060cd35c0x060cd328

即使它们都处理相同的全局变量,为什么地址不同?

这些地址与nm输出的相同符号如何相关:07156fcc b g_classTwo

+0

为了清楚起见,这两个函数从不同的文字池中加载不同的地址。 (“转化为”并不是最清楚的描述,起初我以为你只是说有两个文字池和两个相同指针的副本)。 –

+1

看看它在加载它们后立即对每个偏移量做什么。 .. – Notlikethat

回答

2

ClassOne::first()您有:

1089c64: e59f3014 ldr r3, [pc, #20] ; 1089c80 <ClassOne::first()+0x30> 
1089c68: e08f3003 add r3, pc, r3 
1089c6c: e1a00003 mov r0, r3 
... 
1089c80: 060cd35c .word 0x060cd35c 

ClassOne::second()您有:

1089c98: e59f3014 ldr r3, [pc, #20] ; 1089cb4 <ClassOne::second()+0x30> 
1089c9c: e08f3003 add r3, pc, r3 
1089ca0: e1a00003 mov r0, r3 
... 
1089cb4: 060cd328 .word 0x060cd328 

在这两种,r0this指针(g_classTwo)。如您所见,将文字池中的地址加载到r3之后,将其加总到pc以获得r0

ClassOne::first(),你得到r0 = pc + r3 = 0x01089c70 + 0x060cd35c = 0x07156fcc

ClassOne::second(),你得到r0 = pc + r3 = 0x01089ca4 + 0x060cd328 = 0x07156fcc

所以对于this指针是0x07156fcc,这是g_classTwo的地址。

+0

你有PC值错误 - 他们将分别为0x1089c70和0x1089ca4。这也与'g_classTwo'的地址已知为0x07156fcc相关。 – Notlikethat

+0

@Notlikethat固定。我使用'PC-4'让'LDR'感到困惑,为什么? –

+0

即时是_decimal_ 20,即0x14。 – Notlikethat