c++ - 程序集,全局变量

标签 c++ assembly arm

我有以下源代码:

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

这两种方法都使用 pc 相对偏移量加载 g_classTwo 的地址:ldr r3, [pc, #20],转换为 0x060cd35c0x060cd328 分别为第一种和第二种方法。

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

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

最佳答案

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的地址。

关于c++ - 程序集,全局变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39590382/

相关文章:

pointers - 在汇编中通过引用传递

assembly - 我无法理解 ARM 堆栈操作是如何工作的

gcc - ARM gentoo crossdev 与 uclibc : need OABI rather than EABI

linux - 交叉编译隧道

c++ - 单个函数指针能否指向多个类的成员函数

c++ - 删除 vector 中的字符串

c++ - 在 C++ 中有效识别字符串数组中重复项的算法

c - 为什么人口计数的输入参数必须是无符号的

c - STM32 Bare Metal C - 无法让 LED 工作

c++ - 如何在Processing中制作旋转摄像机?