【问题标题】:How to translate from nasm to gas this code?如何从 nasm 转换为 gas 这段代码?
【发布时间】:2021-09-05 10:18:46
【问题描述】:

只是一个简单的问题。

nasm 代码:​​

memset:
    cld
    mov ecx,edx
    mov al,sil
    rep stosb
    ret

我翻译了第一个块,但不知道如何翻译剩余的行:

memset:
    cld
    movl %edx,%ecx
    movb $sil, %al

对吗?以及如何翻译:

rep stosb
ret

【问题讨论】:

  • movb $sil, %al 当然应该是movb %sil, %al。其余的应该没问题。
  • rep stosbret 在 GAS 中完全一样。
  • nasm -felf64 foo.asm组装,用objdump -drwC foo.o拆卸。此外,mov eax, esi 会更有效,通过替换而不是合并到旧 RAX 来避免对旧 RAX 的错误依赖。

标签: assembly nasm gnu-assembler


【解决方案1】:

通常,您可以使用反汇编程序向您展示其他语法中的指令是什么样的。尽管有时它过于冗长,例如使用rep stos %al,%es:(%rdi) 而不是
rep stosb(这有效的 GAS AT&T 语法:当英特尔助记符已经使用 AT&T 样式操作数时-size 后缀,用 GAS 就可以了。)

或者使用retq 而不仅仅是ret。 (What is callq instruction?)

nasm -felf64 foo.asm
objdump -drwC foo.o
    or objdump -drwC -Mintel foo.o   for GNU .intel_syntax noprefix asm

Agner Fog's objconv 甚至可以反汇编成现成的 asm 源代码,机器码为 cmets。这比使用管道objdump -d | cut -b 32- 剥离它更有效,因为后者会丢弃符号。但是它的 GAS 模式只能针对 GAS .intel_syntax noprefix 类似 MASM 的语法,而不是 AT&T。

objconv -fgasm  foo.o  foo.S    # uses .intel_syntax noprefix

(要在终端上查看它或通过管道进入less,请使用/dev/stdout 作为目标文件)


另一个方向也一样,用gcc -cas组装,用objconv -fnasm拆机。 ndisasm -b64 foo.o 不理解元数据,因此要使用它,您必须将 .text 部分提取到平面二进制文件中,或者通过不应该是机器代码的 ELF 标头字节的无意义反汇编。


一种不太完美的方法是用于寻址模式、跳转和涉及符号的常量。虽然由于您没有一直链接到目标文件,但符号名称应该主要存在于反汇编程序可以使用它们的地方。对于 objdump 输出,您必须将带有符号注释的数字目标整理成实际汇编的内容。 (objconv 为分支目标发明了标签,以制作可以实际组装的 asm。)

幸运的是,objdump 通常不会使用像 %ds: 这样的冗余前缀来向您展示 AT&T 模式下的默认值,但它在 Intel 语法模式下会区分数字地址和立即数,比如 ds:0 (在机器代码只有占位符的 .o 中)。如果你确实看到类似的东西,你会想把它去掉。

  ## objdump -drwC -Mintel output for  mov eax, [foo]  and [rel foo] with extern foo
   8:   8b 04 25 00 00 00 00    mov    eax,DWORD PTR ds:0x0     b: R_X86_64_32S foo
   f:   8b 0d 00 00 00 00       mov    ecx,DWORD PTR [rip+0x0]        # 15 <memset+0x15>        11: R_X86_64_PC32       foo-0x4

Or AT&T
   8:   8b 04 25 00 00 00 00    mov    0x0,%eax b: R_X86_64_32S foo
   f:   8b 0d 00 00 00 00       mov    0x0(%rip),%ecx        # 15 <memset+0x15> 11: R_X86_64_PC32       foo-0x4

所以你想把它翻译成

.intel_syntax noprefix
   mov    eax, foo
   mov    ecx, [rip + foo]

.att_syntax
   mov    foo, %eax         # absolute [disp32] address, only do this in 32-bit code
   mov    foo(%rip), %ecx   # good RIP-relative

另外,mov eax, esi 会更有效,通过替换而不是合并到旧 RAX 来避免对旧 RAX 的错误依赖。还保存了一个 REX 前缀。

【讨论】:

  • 注意objdump 有时会给出不是很惯用的反汇编。例如 GAS 接受简单的rep stosb,但 objdump 将其反汇编为 rep stos %al,%es:(%rdi),这被 GAS 接受但不会被大多数程序员编写。同样,它将ret 反汇编为retq
  • @NateEldredge:很好,谢谢。已更新。
【解决方案2】:

根据 Jester 和 Nate Eldredge 在 cmets 中的提示,答案似乎如下所示:

memset:
    cld
    movl %edx,%ecx
    movb %sil, %al
    rep stosb
    ret

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-10-17
    • 1970-01-01
    • 2021-03-01
    • 2020-04-29
    • 1970-01-01
    • 2020-08-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多