如何获取`mov rdx,symbol`以移动clang intel语法中的符号地址而不是符号地址处的值?

问题描述 投票:1回答:1

我有以下代码,正在macOS上与clang一起使用:

.intel_syntax noprefix

.data

hello:  .ascii  "Hello world\n"
hello_len = . - hello

.text

.globl  _main

_main:
        mov     rax, 0x2000004
        mov     rdi, 1
        lea     rsi, [rip + hello]
        mov     rdx, hello_len       # <-------
        syscall

        mov     rax, 0x2000001
        syscall

虽然看起来它应该打印“ Hello World”并退出,但实际上是段错误。原来是因为mov rdx, hello_len实际上试图移动地址hello_len上的值,而不是hello_len本身的值。

如果我使用AT&T语法,则该行将为movq $hello_len, %rdx,可以正常工作。 clang的GAS intel语法版本等效于什么?

assembly clang x86-64 gas intel-syntax
1个回答
1
投票

使用真实的GAS(在Linux上,您的代码可以随意组合为mov rdx, sign_extended_imm32

但是,很遗憾,c将其组装为mov rdx, [0xc]。那可能是bug,也可能不是bug,但这绝对是不兼容的。 (MacOS的gcc命令根本不是GNU编译器集合,它是Apple Clang(LLVM后端,clang前端。))

OFFSET hello_len似乎不起作用。 (我错误地认为它会在最初的猜测中出现,但是只是尝试了一下。)


尽管clang -S会打印mov edi, offset hello,但不会使用clang的内置汇编器进行汇编! https://godbolt.org/z/x7vmm4。我不确定如何获取clang intel语法以使用符号的值(地址)作为立即数。

// hello.c
char hello[] = "abcdef";
char *foo() { return hello; }
$ clang -fno-pie -O1 -S -masm=intel hello.c
$ clang -c hello.s
hello.s:10:18: error: cannot use more than one symbol in memory operand
        mov     eax, offset hello
                            ^
$ clang --version
clang version 8.0.1 (tags/RELEASE_801/final)
Target: x86_64-pc-linux-gnu
   ...

Clang甚至无法组装自己的.intel_syntax noprefix输出。可能没有解决方案:(

IMO这是一个错误,您应该在铛的https://bugs.llvm.org]中报告它mov r32, imm32而不是相对于RIP的LEA来利用静态地址位于虚拟地址空间的低32位中。当然不是mov r64, imm64。]

© www.soinside.com 2019 - 2024. All rights reserved.