如何从 nasm 转换为 gas 这段代码?
How to translate from nasm to gas this code?
简单的问题。
nasm代码:
memset:
cld
mov ecx,edx
mov al,sil
rep stosb
ret
我翻译了第一段但不知道如何翻译剩余的行:
memset:
cld
movl %edx,%ecx
movb $sil, %al
是吗?以及如何翻译:
rep stosb
ret
根据 Jester 和 Nate Eldredge 的评论提示,答案似乎是这样的:
memset:
cld
movl %edx,%ecx
movb %sil, %al
rep stosb
ret
通常,您可以获得一个 disassembler 来向您展示其他语法中的指令是什么样的。虽然有时它过于冗长,比如使用 rep stos %al,%es:(%rdi)
而不是
rep stosb
(其中 是 有效的 GAS AT&T 语法:当英特尔助记符已经使用 AT&T 风格的 operand-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
甚至可以将 assemble 分解成 ready-to-use asm 源代码,并将机器代码作为注释。这甚至比管道 objdump -d | cut -b 32-
去除它更好,后者会丢弃符号。但是它的GAS模式只能针对GAS .intel_syntax noprefix
MASM-like语法,不能针对AT&T.
objconv -fgasm foo.o foo.S # uses .intel_syntax noprefix
(要在终端或管道中查看它到 less
,请使用 /dev/stdout
作为目标文件)
另一个方向类似,assemble与gcc -c
或as
,disassemble与objconv -fnasm
。 ndisasm -b64 foo.o
不理解元数据,因此要使用它,您必须将 .text
部分提取到平面二进制文件中,或者费力地对 ELF header 字节进行无意义的反汇编t 应该是机器码。
一种不完美的方法是寻址模式、跳转和涉及符号的常量。虽然由于您没有一直链接到 object 文件,符号名称应该主要出现在 disassemblers 可以使用它们的地方。对于 objdump 输出,您必须将带有符号注释的数字目标整理成实际 assemble 的内容。 (objconv
为分支目标发明了标签,使 asm 实际上可以 assemble。)
幸运的是,objdump
通常不会使用像 %ds:
这样的冗余前缀,只是为了向您展示 AT&T 模式下的默认值,但它在 Intel-syntax 模式下会消除数字地址的歧义来自立即数,例如 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 前缀。
简单的问题。
nasm代码:
memset:
cld
mov ecx,edx
mov al,sil
rep stosb
ret
我翻译了第一段但不知道如何翻译剩余的行:
memset:
cld
movl %edx,%ecx
movb $sil, %al
是吗?以及如何翻译:
rep stosb
ret
根据 Jester 和 Nate Eldredge 的评论提示,答案似乎是这样的:
memset:
cld
movl %edx,%ecx
movb %sil, %al
rep stosb
ret
通常,您可以获得一个 disassembler 来向您展示其他语法中的指令是什么样的。虽然有时它过于冗长,比如使用 rep stos %al,%es:(%rdi)
而不是
rep stosb
(其中 是 有效的 GAS AT&T 语法:当英特尔助记符已经使用 AT&T 风格的 operand-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
甚至可以将 assemble 分解成 ready-to-use asm 源代码,并将机器代码作为注释。这甚至比管道 objdump -d | cut -b 32-
去除它更好,后者会丢弃符号。但是它的GAS模式只能针对GAS .intel_syntax noprefix
MASM-like语法,不能针对AT&T.
objconv -fgasm foo.o foo.S # uses .intel_syntax noprefix
(要在终端或管道中查看它到 less
,请使用 /dev/stdout
作为目标文件)
另一个方向类似,assemble与gcc -c
或as
,disassemble与objconv -fnasm
。 ndisasm -b64 foo.o
不理解元数据,因此要使用它,您必须将 .text
部分提取到平面二进制文件中,或者费力地对 ELF header 字节进行无意义的反汇编t 应该是机器码。
一种不完美的方法是寻址模式、跳转和涉及符号的常量。虽然由于您没有一直链接到 object 文件,符号名称应该主要出现在 disassemblers 可以使用它们的地方。对于 objdump 输出,您必须将带有符号注释的数字目标整理成实际 assemble 的内容。 (objconv
为分支目标发明了标签,使 asm 实际上可以 assemble。)
幸运的是,objdump
通常不会使用像 %ds:
这样的冗余前缀,只是为了向您展示 AT&T 模式下的默认值,但它在 Intel-syntax 模式下会消除数字地址的歧义来自立即数,例如 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 前缀。