如何使用 GNU GAS 汇编器生成像 nasm -f bin 这样的普通二进制文件?

发布于 2024-11-26 05:18:35 字数 424 浏览 2 评论 0原文

我有一些 NASM 文件,通常具有以下结构:

        [BITS 64]
        [ORG 0x0000000000200000]

start:
        ...

        ret

我像这样组装它们:

nasm -f bin abc.asm

我想使用 GAS 来编写其中一些文件。两个问题:

  • 我应该在 GAS 中使用哪些指令?我找到了“.org”指令,但 GAS 似乎没有“.bits”指令。

  • 我应该将什么传递给 gccas 来生成纯二进制文件?即 -f bin 选项对 NASM 的作用。

I have some NASM files that generally have the structure:

        [BITS 64]
        [ORG 0x0000000000200000]

start:
        ...

        ret

I'm assembling them like so:

nasm -f bin abc.asm

I'd like to write some of these using GAS instead. Two questions:

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

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

拥有 2024-12-03 05:18:35

我应该在 GAS 中使用哪些指令?我找到了“.org”指令,但 GAS 似乎没有“.bits”指令。

我的汇编器默认为 64 位,您可以在命令行上使用 --32--64 进行选择。请查看 as 的手册,了解如何更改代码内的架构,如果需要(例如.code16可用于为引导加载程序生成实模式代码)。

您很可能不想使用 .org 指令来指定代码所在的位置,但可能希望使用链接脚本或指定在命令上加载文本和数据段的位置线。 (org 0x0000000000200000 生成 2+ MB 的二进制文件)。

我应该将什么传递给 gcc 或 as 来生成纯二进制文件?即 -f bin 选项对 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 <.数据>: 0: 48 31 c0 异或 %rax,%rax 3:48 8b 04 25 0c 00 20 移动0x20000c,%rax 答:00 b: c3 retq
c:78 56 js 0x64 e: 34 12 xor $0x12,%al 10:78 56 js 0x68 12: 34 12 异或 $0x12,%al

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

睡美人的小仙女 2024-12-03 05:18:35

objcopy -O binary

一个不错的选择是:

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

相对于 ld --oformat binary 的优点是使用符号进行调试更容易:

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

另请参阅:https://stackoverflow.com/a/32960272/895245

链接器script

-Ttext 适合快速和肮脏的测试,但对于严肃的工作,您应该使用脚本来提高鲁棒性。

否则,ld 将使用用于用户态应用程序的默认脚本 (ld --verbose),该脚本与您的应用程序不同。

如果没有更多信息,我可以提供的最小脚本是:

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

然后将其与 -T 一起使用:

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

但是您可能希望根据您的具体应用程序修改该脚本。

另请参阅: 有没有办法获取 gcc输出原始二进制文件?

我有一个存储库,其中包含一些常见用例的工作示例:

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:

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文