Inspired by Olivier Poudade's 42 bytes version http://olivier.poudade.free.fr/src/tiny4gb.asm.txt ;June 30th 2015 11:05:37 ;> Peter Ferrie wrote : ;> This one doesn't assume that memory is zero, and can also run from ;> floppy (bp isn't zero in that case). ; My 37 bytes version: push 0cfh ; gdt descriptor cf=present,ring 0 DPL,data,expand-up,writable push 9300h ; gdt descriptor 93h=32-bit page-granularity, accessed push ss push -1 ; gdt descriptor segment limit push ss push ss push ss push 0fh ; gdt descriptor gdt size-1 nb:00*=base a00-a15,base a16-a23,segment access rights,limit 19:16+flags,base a24-a31 mov bx,sp mov [bx+2],bx ; gdt descriptor gdt address lgdt [bx] ; load gdt table mov eax,cr0 ; switch to pmode xormode:xor al,1 ; 1st=>set pmode bit LSbit=1(or al,1;switch to protected mode), set a second bit in CR0 mov cr0,eax ; set control register 0 LSb push 8 ; select descriptor 1 aka NULL descriptor entry 0 of Descriptor Table pop ds jpe xormode ; PF=1=>set pmode bit LSbit=0(and al,0feh;back to real mode) push ss pop ds ; pop ds/restore big real mode @here ss=0 (from MBR entry register status) now DS can access 4gb mov bx,0f01h ; excluded from footprint / attrib+character mov [dword 0b8000h],bx ; excluded from footprint / 32-bit offset with default DS descriptor ; My 36 bytes version: push 0cfh ; gdt descriptor cf=present,ring 0 DPL,data,expand-up,writable push 9300h ; gdt descriptor 93h=32-bit page-granularity, accessed push ss push -1 ; gdt descriptor segment limit push ss push ss push ss mov eax,cr0 push ax ; gdt descriptor gdt size (10h) nb:00*=base a00-a15,base a16-a23,segment access rights,limit 19:16+flags,base a24-a31 mov bx,sp mov [bx+2],bx ; gdt descriptor gdt address lgdt [bx] ; load gdt table xormode:xor al,1 ; 1st=>set pmode bit LSbit=1(or al,1;switch to protected mode), set a second bit in CR0 mov cr0,eax ; set control register 0 LSb push 8 ; select descriptor 1 aka NULL descriptor entry 0 of Descriptor Table pop ds jpe xormode ; PF=1=>set pmode bit LSbit=0(and al,0feh;back to real mode) push ss pop ds ; pop ds/restore big real mode @here ss=0 (from MBR entry register status) now DS can access 4gb mov bx,0f01h ; excluded from footprint / attrib+character mov [dword 0b8000h],bx ; excluded from footprint / 32-bit offset with default DS descriptor ; My 35 bytes version: push ss inc sp push 093cfh ; gdt descriptor cf=present,ring 0 DPL,data,expand-up,writable 93h=32-bit page-granularity, accessed push ss push -1 ; gdt descriptor segment limit push ss push ss push ss mov eax,cr0 push ax ; gdt descriptor gdt size (10h) nb:00*=base a00-a15,base a16-a23,segment access rights,limit 19:16+flags,base a24-a31 mov bx,sp mov [bx+2],bx ; gdt descriptor gdt address lgdt [bx] ; load gdt table xormode:xor al,1 ; 1st=>set pmode bit LSbit=1(or al,1;switch to protected mode), set a second bit in CR0 mov cr0,eax ; set control register 0 LSb push 8 ; select descriptor 1 aka NULL descriptor entry 0 of Descriptor Table pop ds jpe xormode ; PF=1=>set pmode bit LSbit=0(and al,0feh;back to real mode) push ss pop ds ; pop ds/restore big real mode @here ss=0 (from MBR entry register status) now DS can access 4gb inc sp ; excluded from footprint / restore stack alignment mov bx,0f01h ; excluded from footprint / attrib+character mov [dword 0b8000h],bx ; excluded from footprint / 32-bit offset with default DS descriptor My 34 bytes version: dec sp ; unsafe - assumes top of stack contains a zero push 093cfh ; gdt descriptor cf=present,ring 0 DPL,data,expand-up,writable 93h=32-bit page-granularity, accessed push ss push -1 ; gdt descriptor segment limit push ss push ss push ss mov eax,cr0 push ax ; gdt descriptor gdt size (10h) nb:00*=base a00-a15,base a16-a23,segment access rights,limit 19:16+flags,base a24-a31 mov bx,sp mov [bx+2],bx ; gdt descriptor gdt address lgdt [bx] ; load gdt table xormode:xor al,1 ; 1st=>set pmode bit LSbit=1(or al,1;switch to protected mode), set a second bit in CR0 mov cr0,eax ; set control register 0 LSb push 8 ; select descriptor 1 aka NULL descriptor entry 0 of Descriptor Table pop ds jpe xormode ; PF=1=>set pmode bit LSbit=0(and al,0feh;back to real mode) push ss pop ds ; pop ds/restore big real mode @here ss=0 (from MBR entry register status) now DS can access 4gb inc sp ; excluded from footprint / restore stack alignment mov bx, 0f01h ; excluded from footprint / attrib+character mov [dword 0b8000h],bx ; excluded from footprint / 32-bit offset with default DS descriptor