https://github.com/akkartik/mu/blob/main/baremetal/101screen.subx
 1 # Primitives for screen control.
 2 #
 3 # We need to do this in machine code because Mu doesn't have global variables
 4 # yet (for the start of video memory).
 5 
 6 == code
 7 
 8 pixel-on-real-screen:  # x: int, y: int, color: int
 9     # . prologue
10     55/push-ebp
11     89/<- %ebp 4/r32/esp
12     # . save registers
13     50/push-eax
14     51/push-ecx
15     # bounds checks
16     8b/-> *(ebp+8) 0/r32/eax
17     3d/compare-eax-and 0/imm32
18     7c/jump-if-< $pixel-on-real-screen:end/disp8
19     3d/compare-eax-and 0x400/imm32/screen-width=1024
20     7d/jump-if->= $pixel-on-real-screen:end/disp8
21     8b/-> *(ebp+0xc) 0/r32/eax
22     3d/compare-eax-and 0/imm32
23     7c/jump-if-< $pixel-on-real-screen:end/disp8
24     3d/compare-eax-and 0x300/imm32/screen-height=768
25     7d/jump-if->= $pixel-on-real-screen:end/disp8
26     # eax = y*1024 + x
27     8b/-> *(ebp+0xc) 0/r32/eax
28     c1/shift 4/subop/left %eax 0xa/imm8
29     03/add-> *(ebp+8) 0/r32/eax
30     # eax += location of frame buffer
31     03/add-> *0x7f28 0/r32/eax  # unsafe
32     # *eax = color
33     8b/-> *(ebp+0x10) 1/r32/ecx
34     88/byte<- *eax 1/r32/CL
35 $pixel-on-real-screen:end:
36     # . restore registers
37     59/pop-to-ecx
38     58/pop-to-eax
39     # . epilogue
40     89/<- %esp 5/r32/ebp
41     5d/pop-to-ebp
42     c3/return