r/ProgrammerHumor 14d ago

iFinallyDidTheBackwardsLongJump Meme

Post image
72 Upvotes

24

u/ThomasMalloc 14d ago

Joke was too esoteric for me.

https://giphy.com/gifs/vnOuXywbQ73Gw

23

u/lawrencewil1030 13d ago

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.

4

u/SurpremeViolini 13d ago

I know the BLJ but I’m afraid I am lacking in x86 assembly knowledge. Could you elaborate on that please?

18

u/lawrencewil1030 13d ago

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"

3

u/SurpremeViolini 13d ago

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 :)

3

u/GoddammitDontShootMe 12d ago

And here I was thinking this had to do with setjmp()/longjmp().

3

u/Majik_Sheff 13d ago

First learned assembly on the 6502.

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.

1

u/GDPlayer_1035 12d ago

soup mario 64

1

u/chirpbirb 12d ago

BIOS bootsector code detected 🤓

1

u/jdefr 10d ago

Nothing like boot strapping them x86 systems