jart / blink

tiniest x86-64-linux emulator
ISC License
7k stars 224 forks source link

example from website seems broken #156

Open castilma opened 12 months ago

castilma commented 12 months ago

I'm on linux x86_64, trying to follow this example:

$ echo '        .code16
        .globl  _start
_start: dec     %ax
        jmp     _start
' | as -o prog.o
$ ld -static --oformat=binary prog.o -o prog.bin
$  xxd -a prog.bin 
00000000: 0400 0000 2000 0000 0500 0000 474e 5500  .... .......GNU.
00000010: 0200 01c0 0400 0000 0000 0000 0000 0000  ................
00000020: 0100 01c0 0400 0000 0100 0000 0000 0000  ................
00000030: 0000 0000 0000 0000 0000 0000 0000 0000  ................
*
00001000: 48eb fd                                  H..
$ blinkenlights-2022-05-12.com -r prog.bin
^C  (nothing is printed, but one core is busy)
$ blinkenlights-2022-05-12.com -t -r prog.bin 

blinken-init after taking one step, it seems the whole file is being executed as code, including the data in the beginning: blinken-step

Is this wanted? I expected the assembler to create a file with just two instructions. I don't see any jmp instruction.

$ objdump -d prog.o

prog.o:     file format elf64-x86-64

Disassembly of section .text:

0000000000000000 <_start>:
   0:   48 eb fd                rex.W jmp 0 <_start>
ghaerr commented 12 months ago

Hello @castilma,

after taking one step, it seems the whole file is being executed as code, including the data in the beginning:

Yes, that is exactly what's happening - the "binary" file has a 4096 byte header before the instruction code.

The problem you're having is that the ld output prog.bin is in a binary format that isn't in fact compatible with blinkenlights -r. (Yes, it seems the example given using ld -static --oformat=binary prog.o -o prog.bin isn't working: you'll notice that that produces a file with 4096 byte header, then the instructions you're looking for at offset 0x1000 (48eb fd)).

To produce a raw binary file with the two instructions, use the first example on web page:

printf '\100\353\375' >prog.bin

Try that, it will then allow you to observe how blinkenlights operates on raw binary files.

There are other ways of producing 16-bit code for blinkenlight's real mode emulation using the ia16-elf-gcc toolchain, for example. For basic experimentation, you could use the example method and remove the first 4096 bytes of the file using something like dd bs=4096 skip=1 < prog.bin > out.bin.

Thank you!