在 as86/bin86 中包含二进制文件
Include binary file in as86/bin86
我用 i8086 汇编器编写了一些代码,应该将 80x25 图像放入 VRAM 并在屏幕上显示。
entry start
start:
mov di,#0xb800 ; Point ES:DI at VRAM
mov es,di
mov di,#0x0000
mov si,#image ; And DS:SI at Image
mov cx,#0x03e8 ; Image is 1000 bytes
mov bl,#0x20 ; Print spaces
; How BX is used:
; |XXXX XXXX XXXXXXXX|
; ^^^^^^^^^ BL contains ascii whitespace
; ^^^^ BH higher 4 bits contain background color
; ^^^^ BH lower 4 bits contain unused foreground color
img_loop:
seg ds ; Load color
mov bh,[si]
seg es ; Write a whitespace and color to VRAM
mov [di],bx
add di,#2 ; Advance one 'pixel'
sal bh,#4 ; Shift the unused lower 4-bits so that they become background color for the 2nd pixel
seg es
mov [di],bx
add di,#2
add si,#1
sub cx,#1 ; Repeat until 1 KiB is read
jnz img_loop
endless:
jmp endless
image:
GET splash.bin
问题是我无法让 as86 汇编程序包含图像文件中的二进制数据。我查看了 the man page,但找不到任何有用的东西。
如果我尝试构建上面的代码,它不会给我任何错误,但是链接器生成的输出文件大小只有 44 字节,所以显然它没有费心放入 1000 字节的图像。
有人可以帮我吗?我做错了什么?
我不确定这是否对您有帮助,因为我从未尝试过使用 8086 代码。但你也许可以让它发挥作用。
objcopy
程序可以将二进制对象转换为各种不同的格式。就像 man objcopy
页面中的这个例子:
objcopy -I binary -O <output_format> -B <architecture> \
--rename-section .data=.rodata,alloc,load,readonly,data,contents \
<input_binary_file> <output_object_file>
因此,您将在名为 .rodata
的部分中获得一个带有 <input_binary_file>
的目标文件。但是你可以随意命名。然后使用 linker 将您的机器代码 link 转换为图像数据。
符号名称也是为您创建的。同样来自手册页:
-B
--binary-architecture=bfdarch
Useful when transforming a architecture-less input file into an object file. In this case the output architecture can be set to
bfdarch. This option will be ignored if the input file has a known
bfdarch. You can access this binary data inside a program by
referencing the special symbols that are created by the conversion
process. These symbols are called _binary_objfile_start,
_binary_objfile_end and _binary_objfile_size. e.g. you can transform a picture file into an object file and then access it in your code using
these symbols.
如果您的整个代码都是纯代码(没有可执行文件头,没有重定位...),您可以在代码末尾手动连接图像(当然还可以删除 GET splash.bin
)。例如,在 Linux 中,您可以执行 cat code-binary image-binary > final-binary
.
谢谢大家帮助我。不幸的是我没有让 objcopy
工作(也许我太愚蠢了,谁知道呢)虽然我一开始实际上使用了 cat
,但我不得不很快包含多个二进制文件,这应该仍然是可通过我的 assembler 代码中的标签访问,因此这也不是解决方案。
我最后做了以下事情:您在 assembler 源代码中保留了您想要放入二进制文件的标签后的确切字节数,即:
splash_img:
.SPACE 1000
snake_pit:
.SPACE 2000
然后你 assemble 你的源代码通过添加 -s 选项创建一个符号 table,即 -s snake.symbol
到你对 as86 的调用。链接器调用不会改变。现在你有一个二进制文件,在你想要二进制数据的位置有一堆零,你有一个符号 table 看起来应该类似于:
0 00000762 ---R- snake_pit
0 0000037A ---R- splash_img
您现在要做的就是获取一个程序,用您的二进制包含文件覆盖链接器创建的二进制文件,该文件从符号 table 中找到的地址开始。看你怎么想,有很多方法,我最后写了a small C program that does this。
然后我只调用 ./as86_binin snake snake.symbols splash_img splash.bin
并将二进制包含复制到我链接的 assembler 程序中。
很抱歉现在回答我自己的问题,但我觉得这是最好的方法。非常不幸的是 bin86 本身没有简单的二进制包含宏。如果以后有其他人遇到这个问题,我希望这对你有所帮助。
我用 i8086 汇编器编写了一些代码,应该将 80x25 图像放入 VRAM 并在屏幕上显示。
entry start
start:
mov di,#0xb800 ; Point ES:DI at VRAM
mov es,di
mov di,#0x0000
mov si,#image ; And DS:SI at Image
mov cx,#0x03e8 ; Image is 1000 bytes
mov bl,#0x20 ; Print spaces
; How BX is used:
; |XXXX XXXX XXXXXXXX|
; ^^^^^^^^^ BL contains ascii whitespace
; ^^^^ BH higher 4 bits contain background color
; ^^^^ BH lower 4 bits contain unused foreground color
img_loop:
seg ds ; Load color
mov bh,[si]
seg es ; Write a whitespace and color to VRAM
mov [di],bx
add di,#2 ; Advance one 'pixel'
sal bh,#4 ; Shift the unused lower 4-bits so that they become background color for the 2nd pixel
seg es
mov [di],bx
add di,#2
add si,#1
sub cx,#1 ; Repeat until 1 KiB is read
jnz img_loop
endless:
jmp endless
image:
GET splash.bin
问题是我无法让 as86 汇编程序包含图像文件中的二进制数据。我查看了 the man page,但找不到任何有用的东西。
如果我尝试构建上面的代码,它不会给我任何错误,但是链接器生成的输出文件大小只有 44 字节,所以显然它没有费心放入 1000 字节的图像。
有人可以帮我吗?我做错了什么?
我不确定这是否对您有帮助,因为我从未尝试过使用 8086 代码。但你也许可以让它发挥作用。
objcopy
程序可以将二进制对象转换为各种不同的格式。就像 man objcopy
页面中的这个例子:
objcopy -I binary -O <output_format> -B <architecture> \
--rename-section .data=.rodata,alloc,load,readonly,data,contents \
<input_binary_file> <output_object_file>
因此,您将在名为 .rodata
的部分中获得一个带有 <input_binary_file>
的目标文件。但是你可以随意命名。然后使用 linker 将您的机器代码 link 转换为图像数据。
符号名称也是为您创建的。同样来自手册页:
-B
--binary-architecture=bfdarch
Useful when transforming a architecture-less input file into an object file. In this case the output architecture can be set to bfdarch. This option will be ignored if the input file has a known bfdarch. You can access this binary data inside a program by referencing the special symbols that are created by the conversion process. These symbols are called _binary_objfile_start, _binary_objfile_end and _binary_objfile_size. e.g. you can transform a picture file into an object file and then access it in your code using these symbols.
如果您的整个代码都是纯代码(没有可执行文件头,没有重定位...),您可以在代码末尾手动连接图像(当然还可以删除 GET splash.bin
)。例如,在 Linux 中,您可以执行 cat code-binary image-binary > final-binary
.
谢谢大家帮助我。不幸的是我没有让 objcopy
工作(也许我太愚蠢了,谁知道呢)虽然我一开始实际上使用了 cat
,但我不得不很快包含多个二进制文件,这应该仍然是可通过我的 assembler 代码中的标签访问,因此这也不是解决方案。
我最后做了以下事情:您在 assembler 源代码中保留了您想要放入二进制文件的标签后的确切字节数,即:
splash_img:
.SPACE 1000
snake_pit:
.SPACE 2000
然后你 assemble 你的源代码通过添加 -s 选项创建一个符号 table,即 -s snake.symbol
到你对 as86 的调用。链接器调用不会改变。现在你有一个二进制文件,在你想要二进制数据的位置有一堆零,你有一个符号 table 看起来应该类似于:
0 00000762 ---R- snake_pit
0 0000037A ---R- splash_img
您现在要做的就是获取一个程序,用您的二进制包含文件覆盖链接器创建的二进制文件,该文件从符号 table 中找到的地址开始。看你怎么想,有很多方法,我最后写了a small C program that does this。
然后我只调用 ./as86_binin snake snake.symbols splash_img splash.bin
并将二进制包含复制到我链接的 assembler 程序中。
很抱歉现在回答我自己的问题,但我觉得这是最好的方法。非常不幸的是 bin86 本身没有简单的二进制包含宏。如果以后有其他人遇到这个问题,我希望这对你有所帮助。