在 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 错误。
最佳答案
根据今天的测试,这个问题似乎已在 nasm 版本 2.13.03 中得到修复。 (也在 2.13.02 中,但该版本无论如何都有 macho64 目标的其他问题,re @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: 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)
关于macos - macOS 上的 NASM 间接寻址程序集不正确,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45057358/