我在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字节的图像。
有人可以帮我吗?我做错了什么?
答案 0 :(得分:0)
我不确定这会对你有所帮助,因为我从来没有尝试过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>
因此,您可以在名为<input_binary_file>
的部分中找到包含.rodata
的对象文件。但你可以任意命名。然后使用链接器将机器代码链接到图像数据。
也会为您创建符号名称。同样来自手册页:
-B
--binary架构= bfdarch
将无架构输入文件转换为目标文件时非常有用。在这种情况下,输出架构可以设置为 bfdarch。如果输入文件已知,则将忽略此选项 bfdarch。您可以通过以下方式访问程序内的二进制数据 引用转换创建的特殊符号 处理。这些符号称为_binary_objfile_start, _binary_objfile_end和_binary_objfile_size。例如您可以将图片文件转换为目标文件,然后使用代码在代码中访问它 这些符号。
答案 1 :(得分:0)
如果您的整个代码都是纯代码(没有可执行文件头,没有重定位......),您只需在代码末尾手动连接图像(当然会删除GET splash.bin
)。例如,在Linux中,您可以cat code-binary image-binary > final-binary
。
答案 2 :(得分:0)
谢谢其他人试图帮助我。不幸的是我没有让objcopy
工作(也许我太傻了,谁知道)而我最初实际使用cat
时,我不得不尽快包含多个二进制文件,这应该仍然是可以通过汇编代码中的标签访问,因此也不是解决方案。
我最终做的是以下内容:您希望在您想要放入二进制文件的标签后直接保留汇编源代码中的确切字节数,即:
splash_img:
.SPACE 1000
snake_pit:
.SPACE 2000
然后,通过在调用as86时添加-s选项(即-s snake.symbol
)来组合源代码以创建符号表。链接器调用不会更改。现在你有一个二进制文件,你想要二进制数据的位置有一堆零,你有一个看起来应该类似的符号表:
0 00000762 ---R- snake_pit
0 0000037A ---R- splash_img
现在要做的就是获取一个程序来覆盖链接器创建的二进制文件,其二进制包含文件从符号表中的地址开始。这取决于你是怎么做的,有很多方法,我最后写了a small C program that does this。
然后我只调用./as86_binin snake snake.symbols splash_img splash.bin
并将二进制包复制到我的链接汇编程序中。
我很抱歉现在回答我自己的问题,但我觉得这是最好的方法。非常不幸的是,bin86本身并没有一个简单的二进制包含宏。如果将来有其他人遇到这个问题,我希望这会对你有帮助。