llvm:如何生成x64代码,避免基于RIP的寻址模式?

时间:2015-01-01 11:42:56

标签: c assembly x86 clang llvm

我正在为自定义汇编器和链接器使用clang汇编语言输出。我觉得x86模式很舒服,但不适用于PC相对寻址的x64模式。请考虑以下玩具示例。

C代码:

void sum()
{
    static int a, b;
    static int c;
    c = a + b;
}

x86输出片段:

sum:
    call    .L0$pb
.L0$pb:
    pop     EAX
.Ltmp0:
    add     EAX, _GLOBAL_OFFSET_TABLE_+(.Ltmp0-.L0$pb)
    mov     ECX, DWORD PTR [EAX + sum.a@GOTOFF]
    add     ECX, DWORD PTR [EAX + sum.b@GOTOFF]
    mov     DWORD PTR [EAX + sum.c@GOTOFF], ECX
    ret

x64输出片段:

sum:
    mov     EAX, DWORD PTR [RIP + sum.a]
    add     EAX, DWORD PTR [RIP + sum.b]
    mov     DWORD PTR [RIP + sum.c], EAX
    ret

我的问题是:是否有任何命令行开关允许我在不使用基于RIP的寻址模式的情况下生成x64代码?如果没有,是否可以修改LLVM代码以避免为x64模式生成基于RIP的寻址模式以及如何生成?

1 个答案:

答案 0 :(得分:3)

您需要了解x86-64代码模型(请参阅。例如X86-64 ABI doc或,例如http://eli.thegreenplace.net/2012/01/03/understanding-the-x64-code-models)。默认情况下,代码模型很小 - 预计一切都在2Gb范围内,因此应该使用rip-rel寻址。如果您不想使用rip-rel寻址,那么您需要使用例如大代码模式。传递-mcmodel =大到铿锵,你就完成了。

PS:英特尔asmprinter具有上市质量,语法对于大多数应用来说都不够表达,所以,总是在& t使用。