How to generate plain binaries like nasm -f bin with the GNU GAS assembler?

前端 未结 2 1392
再見小時候
再見小時候 2020-11-27 05:34

I have some NASM files that generally have the structure:

        [BITS 64]
        [ORG 0x0000000000200000]

start:
        ...

        ret
相关标签:
2条回答
  • 2020-11-27 05:59

    objcopy -O binary

    A good option is:

    as -o test.o test.S
    ld -Ttext 0x7C00 -o test.elf test.o
    objcopy -O binary kernel.elf kernel.bin
    

    The advantage over ld --oformat binary is that it is easier to use the symbols to debug via:

    qemu-system-i386 -hda main.img -S -s &
    gdb main.elf -ex 'target remote localhost:1234'
    

    See also: https://stackoverflow.com/a/32960272/895245

    Linker script

    -Ttext is fine for quick and dirty testing, but for serious work you should use a script instead to increase robustness.

    Otherwise, ld will use a default script (ld --verbose) intended for userland application, which does not look like your application.

    Without further information, the minimal script I can give is:

    SECTIONS
    {
        . = 2M;
        .text :
        {
            *(.*)
        }
    }
    

    And then use it with -T:

    as --64 -o test.o test.S
    ld -T linker.ld --oformat binary -o test.bin test.o
    

    But you will likely want to modify that script based on your exact application.

    See also: Is there a way to get gcc to output raw binary?

    I have a repository with working examples for some common use cases:

    • boot sectors
    • multiboot interfacing with C
    0 讨论(0)
  • 2020-11-27 06:05

    What directives should I use in GAS? I've found the '.org' directive but GAS doesn't seem to have a '.bits' directive.

    The assembler defaults to 64--bit for me, you can use --32 or --64 to chose on the command line. Have a look at the manual for as to see how you can change the architecture inside the code if needed (e.g. .code16 can be used to generate real mode code for a boot loader).

    You most likely don't want to use the .org directive to specify where the code is located, but will probably want to use a link script or specify where the text and data segments are loaded on the command line. (org 0x0000000000200000 results in a 2+ MB binary file).

    What should I pass to gcc or as to generate a plain binary file? I.e. what the -f bin option does with NASM.

    $ cat test.S
    .section .text
    .globl _start
    _start:
            xor %rax, %rax
            mov test, %rax
            ret
    
    test: .quad 0x1234567812345678
    
    
    $ as --64 -o test.o test.S
    $ ld -Ttext 200000 --oformat binary -o test.bin test.o
    

    $ objdump -D -b binary -m i386:x86-64 test.bin
    test.bin:     file format binary
    Disassembly of section .data:

    0000000000000000 <.data>: 0: 48 31 c0 xor %rax,%rax 3: 48 8b 04 25 0c 00 20 mov 0x20000c,%rax a: 00 b: c3 retq
    c: 78 56 js 0x64 e: 34 12 xor $0x12,%al 10: 78 56 js 0x68 12: 34 12 xor $0x12,%al

    0 讨论(0)
提交回复
热议问题