【问题标题】:Incorrect NASM indirect addressing assembly on macOSmacOS 上不正确的 NASM 间接寻址程序集
【发布时间】:2017-12-16 20:42:14
【问题描述】:

在 macOS 上组装以下代码:

global start

default rel

section .text

start:
    lea rdx, [buffer + 0]
    lea rdx, [buffer + 1]
    lea rdx, [buffer + 2]
    lea rdx, [buffer + 3]
    lea rdx, [buffer + 4]
    lea rdx, [buffer + 5]
    lea rdx, [buffer + 6]
    lea rdx, [buffer + 7]
    lea rdx, [buffer + 8]


section .data

buffer: db 0,0,0

使用命令nasm -fmacho64 -w+all test.asm -o test.o,产生:(使用gobjdump -d test.o

0000000000000000 <start>:
   0:   48 8d 15 38 00 00 00    lea    0x38(%rip),%rdx        # 3f <buffer>
   7:   48 8d 15 32 00 00 00    lea    0x32(%rip),%rdx        # 40 <buffer+0x1>
   e:   48 8d 15 2c 00 00 00    lea    0x2c(%rip),%rdx        # 41 <buffer+0x2>
  15:   48 8d 15 26 00 00 00    lea    0x26(%rip),%rdx        # 42 <buffer+0x3>
  1c:   48 8d 15 20 00 00 00    lea    0x20(%rip),%rdx        # 43 <buffer+0x4>
  23:   48 8d 15 1a 00 00 00    lea    0x1a(%rip),%rdx        # 44 <buffer+0x5>
  2a:   48 8d 15 14 00 00 00    lea    0x14(%rip),%rdx        # 45 <buffer+0x6>
  31:   48 8d 15 0e 00 00 00    lea    0xe(%rip),%rdx        # 46 <buffer+0x7>
  38:   48 8d 15 08 00 00 00    lea    0x8(%rip),%rdx        # 47 <buffer+0x8>

这看起来是正确的。然后使用ld test.o -o test 将其链接到可执行文件中时,我们得到:(使用gobjdump -d test

0000000000001fc1 <start>:
    1fc1:   48 8d 15 38 00 00 00    lea    0x38(%rip),%rdx        # 2000 <buffer>
    1fc8:   48 8d 15 32 00 00 00    lea    0x32(%rip),%rdx        # 2001 <buffer+0x1>
    1fcf:   48 8d 15 2c 00 00 00    lea    0x2c(%rip),%rdx        # 2002 <buffer+0x2>
    1fd6:   48 8d 15 23 00 00 00    lea    0x23(%rip),%rdx        # 2000 <buffer>
    1fdd:   48 8d 15 1d 00 00 00    lea    0x1d(%rip),%rdx        # 2001 <buffer+0x1>
    1fe4:   48 8d 15 17 00 00 00    lea    0x17(%rip),%rdx        # 2002 <buffer+0x2>
    1feb:   48 8d 15 11 00 00 00    lea    0x11(%rip),%rdx        # 2003 <buffer+0x3>
    1ff2:   48 8d 15 0b 00 00 00    lea    0xb(%rip),%rdx        # 2004 <buffer+0x4>
    1ff9:   48 8d 15 05 00 00 00    lea    0x5(%rip),%rdx        # 2005 <buffer+0x5>

突然,出乎意料,如果 n >= 3,buffer + n 变成了 buffer + (n - 3)。我使用的 nasm 版本是 2.13.01,ld 是 macOS Sierra 的系统链接器,ld -v 给予:

@(#)PROGRAM:ld  PROJECT:ld64-274.2
configured to support archs: armv6 armv7 armv7s arm64 i386 x86_64 x86_64h armv6m armv7k armv7m armv7em (tvOS)
LTO support using: LLVM version 8.0.0, (clang-800.0.42.1)
TAPI support using: Apple TAPI version 1.30

为什么会这样?请注意,相同的代码似乎可以在 linux 上很好地组装和链接,以及使用 yasm。在其他地方,我读到 nasm 在 Mach-O 64 格式方面存在一些奇怪的问题,所以这可能是该领域的 nasm 错误。

【问题讨论】:

  • 现在猜测一下,将buffer的声明扩展为8个字节会是什么结果?
  • @FrankC。将最后一行更改为buffer: db 0,0,0,0, 0,0,0,0 会从buffer+0x8 重新开始计数(从上面的数据推断);将其更改为 buffer: dq 0 会得到完全相同的结果。一般来说,不管buffer的大小,它似乎从缓冲区的末尾开始重新计数,但之后不再重新开始。
  • 请注意,相同的代码使用yasm 绝对可以正常工作,这让我认为这确实是一个 nasm 错误。
  • a NASM bug with 2.13.02+ on OS X,但 MichaelPetch 说 2.13.01 应该没问题。此外,这次已知的错误没有影响 RIP-relative,即the NASM 2.11.08 + macho64 bug。你举报了吗?
  • @PeterCordes 不,我还没有报告。但我刚刚使用从here 下载的 nasm 2.13.0{1,2,3} 版本再次测试; 2.13.01 给出了与问题相同的结果(幸运的是它是可重现的),.02 为“test.o”提供了非常奇怪的输出,但是一个正确的“测试”,并且 .03 给出了与 .02 相同的输出。显然,这个问题已经解决了。

标签: macos nasm x86-64 ld disassembly


【解决方案1】:

这似乎已在 nasm 版本 2.13.03 中得到修复,正如今天测试的那样。 (也在 2.13.02 中,但该版本在 macho64 目标方面仍然存在其他问题,请回复 @MichaelPetch;在这种情况下,.02 的输出与 .03 的相同。) test.asm 和中给出的命令的输出如下问题。

nasm -fmacho64 -w+all test.asm -o test.o; gobjdump -d test.o:

test.o:     file format mach-o-x86-64


Disassembly of section .text:

0000000000000000 <start>:
   0:   48 8d 15 00 00 00 00    lea    0x0(%rip),%rdx        # 7 <start+0x7>
   7:   48 8d 15 01 00 00 00    lea    0x1(%rip),%rdx        # f <start+0xf>
   e:   48 8d 15 02 00 00 00    lea    0x2(%rip),%rdx        # 17 <start+0x17>
  15:   48 8d 15 03 00 00 00    lea    0x3(%rip),%rdx        # 1f <start+0x1f>
  1c:   48 8d 15 04 00 00 00    lea    0x4(%rip),%rdx        # 27 <start+0x27>
  23:   48 8d 15 05 00 00 00    lea    0x5(%rip),%rdx        # 2f <start+0x2f>
  2a:   48 8d 15 06 00 00 00    lea    0x6(%rip),%rdx        # 37 <start+0x37>
  31:   48 8d 15 07 00 00 00    lea    0x7(%rip),%rdx        # 3f <buffer>
  38:   48 8d 15 08 00 00 00    lea    0x8(%rip),%rdx        # 47 <buffer+0x8>

ld test.o -o test; gobjdump -d test:

test:     file format mach-o-x86-64


Disassembly of section .text:

0000000000001fc1 <start>:
    1fc1:       48 8d 15 38 00 00 00    lea    0x38(%rip),%rdx        # 2000 <buffer>
    1fc8:       48 8d 15 32 00 00 00    lea    0x32(%rip),%rdx        # 2001 <buffer+0x1>
    1fcf:       48 8d 15 2c 00 00 00    lea    0x2c(%rip),%rdx        # 2002 <buffer+0x2>
    1fd6:       48 8d 15 26 00 00 00    lea    0x26(%rip),%rdx        # 2003 <buffer+0x3>
    1fdd:       48 8d 15 20 00 00 00    lea    0x20(%rip),%rdx        # 2004 <buffer+0x4>
    1fe4:       48 8d 15 1a 00 00 00    lea    0x1a(%rip),%rdx        # 2005 <buffer+0x5>
    1feb:       48 8d 15 14 00 00 00    lea    0x14(%rip),%rdx        # 2006 <buffer+0x6>
    1ff2:       48 8d 15 0e 00 00 00    lea    0xe(%rip),%rdx        # 2007 <buffer+0x7>
    1ff9:       48 8d 15 08 00 00 00    lea    0x8(%rip),%rdx        # 2008 <buffer+0x8>

值得注意的是,我的ld 已更新,ld -v 现在提供:

@(#)PROGRAM:ld  PROJECT:ld64-305
configured to support archs: armv6 armv7 armv7s arm64 i386 x86_64 x86_64h armv6m armv7k armv7m armv7em (tvOS)
LTO support using: LLVM version 9.0.0, (clang-900.0.39.2) (static support for 21, runtime is 21)
TAPI support using: Apple TAPI version 900.0.15 (tapi-900.0.15)

【讨论】:

  • 2.13.02 版本的 NASM 甚至不被推荐,因为它们也有自己的 macho64 问题:bugzilla.nasm.us/show_bug.cgi?id=3392468
  • @MichaelPatch 谢谢,在答案中注明。我似乎也记得问题,现在我想起来了。已经有一段时间没有使用 nasm 了。
猜你喜欢
  • 2013-06-05
  • 1970-01-01
  • 2022-11-14
  • 2019-07-17
  • 2015-12-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多