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 <xxxxxxxxx@gmail.xxxx> 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