位置独立代码指向错误的地址

时间:2015-07-26 18:24:23

标签: nasm x86-64 mach-o

我有一个针对macho64架构的NASM(2.11.08)编写的小型示例程序。我正在运行OSX 10.10.3:

bits 64

section .data

    msg1    db 'Message One', 10, 0
    msg1len equ $-msg1
    msg2    db 'Message Two', 10, 0
    msg2len equ $-msg2

section .text
    global  _main
    extern  _printf

_main:
    sub     rsp, 8  ; align

    lea     rdi, [rel msg1]
    xor     rax, rax
    call    _printf

    lea     rdi, [rel msg2]
    xor     rax, rax
    call    _printf

    add rsp, 8
    ret

我使用以下命令行编译和链接:

/usr/local/bin/nasm -f macho64 test2.s
ld -macosx_version_min 10.10.0 -lSystem -o test2 test2.o

当我在test2可执行文件上执行对象转储时,这是相关的代码段(如果我错了,我可以发布更多信息!):

0000000000001fb7 <_main>:
1fb7:   48 83 ec 08             sub    $0x8,%rsp
1fbb:   48 8d 3d 56 01 00 00    lea    0x156(%rip),%rdi        # 2118 <msg2+0xf3>
1fc2:   48 31 c0                xor    %rax,%rax
1fc5:   e8 14 00 00 00          callq  1fde <_printf$stub>
1fca:   48 8d 3d 54 00 00 00    lea    0x54(%rip),%rdi        # 2025 <msg2>
1fd1:   48 31 c0                xor    %rax,%rax
1fd4:   e8 05 00 00 00          callq  1fde <_printf$stub>
1fd9:   48 83 c4 08             add    $0x8,%rsp
1fdd:   c3                      retq  

...

0000000000002018 <msg1>:
0000000000002025 <msg2>:

最后,输出:

$ ./test2
Message Two
$

我的问题是,msg1发生了什么?

我假设msg1没有被打印,因为0x14f(%rip)不是正确的地址(只是空值)。

为什么lea edi, [rel msg2]指向正确的地址,而lea edi, [rel msg1]指向msg2时指向NULL?

看起来0x14f(%rip)偏移量恰好是msg1位于内存中的0x100(在这个问题的许多测试中都是如此)。

我在这里缺少什么?

编辑:.data部分中最后出现的消息(msg1或msg2)是唯一可以打印的消息。

1 个答案:

答案 0 :(得分:1)

IDK关于Mach-o ABI,但如果它与SystemV x86-64 ABI GNU / Linux使用的相同,那么我认为你的问题是你需要清除eax来告诉它一个像printf这样的varargs函数,它没有FP。

此外,lea rdi, [rel msg1]将是一个更好的选择。就目前而言,您的代码在虚拟地址空间的低32位内仅与位置无关,因为您将指针截断为32位。

似乎NASM有一个错误。同样的问题又出现了:NASM 2 lines of db (initialized data) seemingly not working。在那里,OP确认数据存在,但标签错误,并希望在上游报告。