JustOneMan
JustOneMan

Reputation: 202

How to translate from nasm to gas this code?

Just simple question.

nasm code:

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

I translated first chunk but don't know how to translate remaining lines:

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

Is it right? And how to translate:

rep stosb
ret

Upvotes: 0

Views: 326

Answers (2)

Peter Cordes
Peter Cordes

Reputation: 364180

In general, you can get a disassembler to show you what instructions look like in the other syntax. Although sometimes it's overly verbose, like using rep stos %al,%es:(%rdi) instead of
rep stosb (which is valid GAS AT&T syntax: when the Intel mnemonics already use AT&T style operand-size suffixes, that's just fine with GAS.)

Or using retq instead of just 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 can even disassemble into ready-to-use asm source, with the machine code as comments. That works even better than piping objdump -d | cut -b 32- to strip that, which would discard symbols. But its GAS mode can only target GAS .intel_syntax noprefix MASM-like syntax, not AT&T.

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

(To see it on the terminal or pipe into less, use /dev/stdout as the destination file)


Similarly for the other direction, assemble with gcc -c or as, disassemble with objconv -fnasm. ndisasm -b64 foo.o doesn't understand metadata, so to use it you'd have to extract the .text section to a flat binary, or wade through the nonsense disassembly of ELF header bytes that aren't supposed to be machine code.


One way this is less than perfect is for addressing modes, jumps, and constants involving symbols. Although since you're not linking all the way to an executable, symbol names should mostly be there in object files where disassemblers can use them. For objdump output, you will have to tidy up the numeric destination with a symbol comment into something that will actually assemble. (objconv invents labels for branch targets to make asm that can actually assemble.)

Fortunately objdump doesn't typically use redundant prefixes like %ds: just to show you what the default was in AT&T mode, but it does in Intel-syntax mode to disambiguate numeric addresses from immediates, like ds:0 (in a .o where the machine code just has placeholders). If you do see stuff like that you'd want to strip it out.

  ## 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

So you'd want to to translate that to

.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

Also, mov eax, esi would be more efficient, avoiding a false dependency on the old RAX by replacing, not merging into it. Also saves a REX prefix.

Upvotes: 2

JustOneMan
JustOneMan

Reputation: 202

As prompted in the comments by Jester and Nate Eldredge the answer seems to look like this:

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

Upvotes: 1

Related Questions