只是个简单的问题。nasm代码:
memset: cld mov ecx,edx mov al,sil rep stosb ret
我翻译了第一个块,但不知道如何翻译剩下的行:
memset: cld movl %edx,%ecx movb $sil, %al
对不对?如何翻译:
rep stosb ret
13z8s7eq1#
通常,您可以使用反汇编程序来向您展示其他语法中的指令。虽然有时它过于冗长,比如使用rep stos %al,%es:(%rdi)而不是
rep stos %al,%es:(%rdi)
rep stosb
或者使用retq而不是仅仅使用ret。(What is callq instruction?)
retq
ret
nasm -felf64 foo.asm objdump -drwC foo.o or objdump -drwC -Mintel foo.o for GNU .intel_syntax noprefix asm
Agner Fog的objconv甚至可以反汇编成现成的asm源代码,机器代码作为注解。这比通过管道objdump -d | cut -b 32-来剥离它(这将丢弃符号)的效果更好。但它的GAS模式只能针对GAS .intel_syntax noprefix MASM类语法,而不是AT & T。
objconv
objdump -d | cut -b 32-
.intel_syntax noprefix
objconv -fgasm foo.o foo.S # uses .intel_syntax noprefix
(To在终端上看到它或管道到less,使用/dev/stdout作为目标文件)另一个方向也一样,用gcc -c或as组装,用objconv -fnasm拆卸。ndisasm -b64 foo.o不理解元数据,因此要使用它,您必须将.text部分提取为平面二进制文件,或者费力地对不应该是机器码的ELF头字节进行无意义的反汇编。一种不太完美的方法是处理涉及符号的模式、跳转和常量。虽然你没有一直链接到一个可执行文件,但是符号名应该主要在对象文件中,反汇编程序可以使用它们。对于objdump输出,您必须使用符号注解整理数字目的地,使其成为实际组装的内容。(objconv为分支目标发明了标签,以使ASM实际上可以组装。)幸运的是,objdump通常不会使用像%ds:这样的冗余前缀来显示AT & T模式下的默认值,但它会在Intel语法模式下消除数字地址与立即数的歧义,比如ds:0(在a. o中,机器码只有占位符)。如果你真的看到这样的东西,你会想把它剥下来。
less
/dev/stdout
gcc -c
as
objconv -fnasm
ndisasm -b64 foo.o
.text
objdump
%ds:
ds:0
## 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前缀。
mov eax, esi
hgncfbus2#
正如Jester和Nate Eldredge的评论所提示的那样,答案似乎是这样的:
memset: cld movl %edx,%ecx movb %sil, %al rep stosb ret
2条答案
按热度按时间13z8s7eq1#
通常,您可以使用反汇编程序来向您展示其他语法中的指令。虽然有时它过于冗长,比如使用
rep stos %al,%es:(%rdi)
而不是rep stosb
**(其中 * 是 * 有效的GAS AT & T语法:当英特尔的助记符已经使用AT & T风格的操作数大小后缀时,GAS就可以了。或者使用
retq
而不是仅仅使用ret
。(What is callq instruction?)Agner Fog的
objconv
甚至可以反汇编成现成的asm源代码,机器代码作为注解。这比通过管道objdump -d | cut -b 32-
来剥离它(这将丢弃符号)的效果更好。但它的GAS模式只能针对GAS.intel_syntax noprefix
MASM类语法,而不是AT & T。(To在终端上看到它或管道到
less
,使用/dev/stdout
作为目标文件)另一个方向也一样,用
gcc -c
或as
组装,用objconv -fnasm
拆卸。ndisasm -b64 foo.o
不理解元数据,因此要使用它,您必须将.text
部分提取为平面二进制文件,或者费力地对不应该是机器码的ELF头字节进行无意义的反汇编。一种不太完美的方法是处理涉及符号的模式、跳转和常量。虽然你没有一直链接到一个可执行文件,但是符号名应该主要在对象文件中,反汇编程序可以使用它们。对于
objdump
输出,您必须使用符号注解整理数字目的地,使其成为实际组装的内容。(objconv
为分支目标发明了标签,以使ASM实际上可以组装。)幸运的是,
objdump
通常不会使用像%ds:
这样的冗余前缀来显示AT & T模式下的默认值,但它会在Intel语法模式下消除数字地址与立即数的歧义,比如ds:0
(在a. o中,机器码只有占位符)。如果你真的看到这样的东西,你会想把它剥下来。所以你要把它翻译成
此外,
mov eax, esi
将更有效,通过替换而不是合并到旧RAX中来避免对旧RAX的错误依赖。还保存REX前缀。hgncfbus2#
正如Jester和Nate Eldredge的评论所提示的那样,答案似乎是这样的: