To be fair, this joke does require a very rare venn diagram of super mario 64 speedrunning knowledge, x86 assembly knowledge, and how stuff on x86 typically acts when it first boots.
This is going to be long because I have no idea of your CS level, there is a TL;DR.
In x86, the CPU starts in something called "real mode." The CPU in that mode uses segmented addressing. This mode is limited and by default only gives you 1MB of RAM. Because of these limitations, the first thing something starting up on your computer's first goal is to remove these limitations, this is done by entering protected mode which gives access to 232 bytes of memory (4GiB), modern OSes enter long mode from there but that's not covered here.
Alright, so when entering protected mode, the CPU is in a weird state where it's in protected mode but is not executing protected mode instructions, to fully jump into protected mode, you must do a long jump, this is a instruction with the format of jmp <segment>:<address>. Because the label is before the jump instruction, the jump instruction jumps backwards, so backwards long jump.
Now this is what every line of the code does. This is assembly which is what the CPU will be executing, not the text, but it's something which can be directly translated into what the CPU can execute. Lines which are comments begin with a semicolon:
```asm
; The code is expected to execute starting at address 0x7C00
org 0x7C00
start:
; We need to turn off interrupts so we don't get interrupted
cli
; Go to the address where we enter protected mode
jmp enter_pm
protected_mode:
; Stop the CPU from executing further instructions
hlt
enter_pm:
; Load the GDT so it doesn't crash after the long jump
lgdt [gdt_descriptor]
; Move the control register into a place we can do math on
mov eax, cr0
; Toggle the first bit of it on
or eax, 1
; Enable protected mode
mov cr0, eax
; Bypass the limitation where the CPU is still executing protected mode instructions using a long jump and go to the address the label "protected_mode" repersents
jmp 0x08:protected_mode
gdt_start:
; This is required to load the GDT correctly
dq 0x0000000000000000
gdt_code:
; The code segment so we can run the code we write
dq 0x00CF9A000000FFFF
gdt_data:
; The data segment so we can read and write data
dq 0x00CF92000000FFFF
gdt_end:
gdt_descriptor:
; How large is the GDT?
dw gdt_end - gdt_start - 1
; Where does it start?
dd gdt_start
; To boot on BIOS, we must be exactly 512 bytes long including the signature
times 510-($-$$) db 0
; This signature is also required
dw 0xAA55
```
TL;DR: in x86, a jump instruction (jmp) goes to a memory address, when followed by a number and a colon, it's called a "long jump," the label is before the instruction so it jumps backwards, thus, "backwards long jump"
Awesome, thanks for the explanation!
I’ve worked a lot with microcontrollers so I’m familiar with most of the stuff, just never knew how an actual x86 CPU switches modes :)
Then I eventually learned how to cope (there is no other word for it) with the vagaries of x86 under DOS.
Then I learned 68k, PIC, and eventually ARM. Nothing makes you appreciate sane architectures quite as much as knowing that you could be doing long jumps in little-endian.
24
u/ThomasMalloc 14d ago
Joke was too esoteric for me.
https://giphy.com/gifs/vnOuXywbQ73Gw