链接extern int值和函数时的不同行为

时间:2015-02-02 09:50:28

标签: ios assembly arm

下面的方法是一个Objective-C方法及其汇编代码,由LLVM生成。

extern int globalInt ;

- (void)systemInfo
{
    add_fun(globalInt, 2) ;
}

    .align  2
    .code   16                      @ @"\01-[utility systemInfo]"
    .thumb_func "-[utility systemInfo]"
"-[utility systemInfo]":
Lfunc_begin2:
    .loc    1 31 0
    .cfi_startproc
@ BB#0:
    push    {r7, lr}
    mov r7, sp
    sub sp, #12
    movs    r2, #2
    movt    r2, #0
    movw    r3, :lower16:(L_globalInt$non_lazy_ptr-(LPC2_0+4))
    movt    r3, :upper16:(L_globalInt$non_lazy_ptr-(LPC2_0+4))
LPC2_0:
    add r3, pc
    ldr r3, [r3]
    str r0, [sp, #8]
    str r1, [sp, #4]
    .loc    1 33 0 prologue_end
Ltmp6:
    ldr r0, [r3]
    mov r1, r2
    bl  _add_fun
    .loc    1 34 0
    str r0, [sp]                @ 4-byte Spill
    add sp, #12
    pop {r7, pc}
Ltmp7:
Lfunc_end2:
    .cfi_endproc

L_globalInt$non_lazy_ptr:
    .indirect_symbol    _globalInt
    .long   0

globalIntadd_fun都在另一个源文件中定义。在汇编代码中,它使用add_fun的名称,但对于globalInt,它使用相对pc样式代码来获取其值。 为什么不能以这种方式使用globalInt

movw r3, :lower16(_globalInt)
movt r3, :upper16(_globalInt)
ldr  r3, [r3]

1 个答案:

答案 0 :(得分:0)

如果globalInt在某种程度上是静态/常量,则编译器会尝试将值嵌入到指令中,但是ARM是一种加载/存储体系结构,并且对于大多数情况下,它需要对值进行操作才能将它们加载到首先注册。

这里它尽可能直接。

movw    r3, :lower16:(L_globalInt$non_lazy_ptr-(LPC2_0+4))
movt    r3, :upper16:(L_globalInt$non_lazy_ptr-(LPC2_0+4))

此地址将嵌入到指令中。

bl  _add_fun