0

I have written a bit of code in i8086 assembler that is supposed to put a 80x25 image into the VRAM and show it on screen.

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

The problem is that I cannot get the as86 assembler to include the binary data from the image file. I have looked at the the man page but I could not find anything that works.

If I try to build above code it gives me no error, but the output file produced by the linker is only 44 bytes in size, so clearly it did not bother to put in the 1000 byte image.

Can anybody help me with that? What am I doing wrong?

Maximilian Schier
  • 1,579
  • 14
  • 18

3 Answers3

0

I am not certain that this will help you, as I have never tried it for 8086 code. But you might be able to make it work.

The objcopy program can convert binary objects to various different formats. Like this example from the man objcopy page:

objcopy -I binary -O <output_format> -B <architecture> \
  --rename-section .data=.rodata,alloc,load,readonly,data,contents \
  <input_binary_file> <output_object_file>

So from that you'd have an object file with your <input_binary_file> in a section named .rodata. But you could name it whatever you wanted. Then use a linker to link your machine code to the image data.

The symbol names are created for you too. Also from the man page:

-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.

Zan Lynx
  • 53,022
  • 10
  • 79
  • 131
0

If your whole code is pure code (no executable headers, no relocation...) you can just manually concatenate the image at the end of the code (and of course remove GET splash.bin). In Linux for example you can do cat code-binary image-binary > final-binary.

m0skit0
  • 25,268
  • 11
  • 79
  • 127
0

Thank you everybody else trying to help me. Unfortunately I did not get the objcopy to work (maybe I am just too stupid, who knows) and while I actually used cat at first, I had to include multiple binary files soon, which should still be accessible via labels in my assembler code, so that was not a solution either.

What I ended up doing was the following: You reserve the exact amount of bytes in your assembler source code directly after the label you wanna put in your binary file, i.e.:

splash_img:
.SPACE 1000
snake_pit:
.SPACE 2000

Then you assemble your source code creating a symbol table by adding the -s option, i.e. -s snake.symbol to your call to as86. The linker call does not change. Now you have a binary file that has a bunch of zeroes at the position you wanna have your binary data, and you have a symbol table that should look similar to this:

0 00000762 ---R- snake_pit
0 0000037A ---R- splash_img

All you gotta do now is get a program to override the binary file created by the linker with your binary include file starting at the addresses found in the symbol table. It is up to you how you wanna do it, there are a lot of ways, I ended up writing a small C program that does this.

Then I just call ./as86_binin snake snake.symbols splash_img splash.bin and it copies the binary include into my linked assembler program.

I am sorry for answering my own question now, but I felt like this is the best way to do it. It is quite unfortunate bin86 doesn't have a simple binary include macro on its own. If anybody else runs into this problem in the future, I hope this will help you.

Maximilian Schier
  • 1,579
  • 14
  • 18