Contrary to other answers, I maintain that, in principle, the short answer is YES . This is most likely not officially supported officially, but it seems to work. At the end of this answer, I present a demo.
Linux-x86_64 32- ( X32 , GDB) CS , 0x23 - 32- 3 , GDT ( 0). 64- : 0x33 - (.. 64-) 3 ( ES, CS, SS, DS 64- ). , - 0x33, CS 64- .
jmp far 64- . , rax, 32-
dec eax
mov eax, 0xfafafafa
ud2
cli ; these two are unnecessary, but leaving them here for fun :)
hlt
, 32- CS ( SIGILL ud2).
( fasm).
format ELF executable
segment readable executable
SYS_EXIT_32BIT=1
SYS_EXIT_64BIT=60
SYS_WRITE=4
STDERR=2
entry $
mov ax,cs
cmp ax,0x23 ; 32 bit process on 64 bit kernel has this selector in CS
jne kernelIs32Bit
jmp 0x33:start64 ; switch to 64-bit segment
start64:
use64
mov rax, qword 0xf4fa0b0ffafafafa ; would crash inside this if executed as 32 bit code
xor rdi,rdi
mov eax, SYS_EXIT_64BIT
syscall
ud2
use32
kernelIs32Bit:
mov edx, msgLen
mov ecx, msg
mov ebx, STDERR
mov eax, SYS_WRITE
int 0x80
dec ebx
mov eax, SYS_EXIT_32BIT
int 0x80
msg:
db "Kernel appears to be 32 bit, can't jump to long mode segment",10
msgLen = $-msg