在 NASM 和 GCC 中提供 incbin 路径作为预定义的宏

Provide incbin path as a predefined macro in both NASM and GCC

我想在可执行文件中嵌入一个二进制文件,以一种可移植到 Windows 和 Linux 的方式。

为了实现这一点,我想使用带有指令 incbin 的汇编文件。例如:

.intel_syntax noprefix


      .global _img0_start
      .global _img0_end
      .global _img0_size


_img0_start:   .incbin "img0.bin"
_img0_end:
_img0_size:    .quad  $ -  _img0_start

在编译上面的汇编文件之前,我不知道二进制文件在哪里,所以我想用宏替换img0.bin,并定义它在命令行参数中,就好像我正在使用 gcc 选项 -D 来定义宏常量。

我看到存在 -d Option: Pre-Define a Macro,它允许执行上述操作,但仅限于数值(我需要提供文件路径)。 (字体:https://www.nasm.us/doc/nasmdoc2.html#section-2.1.19

是否有类似 -d 的东西,但它允许定义字符串,并且适用于 moth gasnasm?

我读了更多,我意识到不需要扩展为字符串的宏。

相反,可以做的只是为二进制文件提供一个固定名称,在我的例子中,img0.bin,然后使用 -I 选项提供额外的路径来搜索此类文件.

换句话说,使用与上面相同的汇编文件(设为assembly_file.s),只需执行:

gcc -c assembly_file.s -I<path_to_folder_that_contains_img0.bin> -o <output_file_name>

NASM 宏和 C 预处理器都允许任意字符串。

NASM equ 常量必须是整数,但 %define foo eaxnasm '-DIMG="foo.bin"' 都有效。

注意宏定义 包括 双引号。 CPP 可以很容易地在双引号内扩展宏,但我没有不用费心检查 NASM 是否可以轻松做到这一点。

通常很容易在 Make 或其他软件中创建 double-quoted 字符串。


;;; foo-nasm.asm  NASM source
incbin IMG
# foo-gas.S   GAS source (capital S gets GCC to run it through CPP)
.incbin IMG

hi.bin 包含 B8 68 69 00 00mov eax, 'hi'

的 32/64 位机器码
 $ gcc -c foo-gas.S -DIMG='"hi.bin"'            
 $ nasm -felf64 foo-nasm.asm -DIMG='"hi.bin"'       

$ disas foo-gas.o
...
0000000000000000 <.text>:
   0:   b8 68 69 00 00          mov    eax,0x6968

$ disas foo-nasm.o
...
0000000000000000 <.text>:
   0:   b8 68 69 00 00          mov    eax,0x6968