Reputation: 334
I needed to write a code to test the LSB of cr0
in nasm. The code is as follows:
section .data
temp : db 00h ;Temporary storage
nl : db 10 ;Memory which holds decimal 10 to print a newline
section .text
global _start
_start:
mov rax,cr0 ;Move contents of cr0 into rax
bt rax,0 ;Test LSB of rax
jnc l1 ;If 0, move 30 into temp (ASCII for '0')
mov byte[temp],31h ;Else, move 31 into temp
jmp l2
l1:
mov byte[temp],30h
l2:
print temp,1 ;Print value of temp
print nl,1
mov rax,60 ;Exit syscall
mov rdi,0
syscall
The code, when run, causes a segmentation fault. It occurs because of the instruction mov rax,cr0
. When that instruction is commented, no segmentation fault occurs. Why is this so? Does this have something to do with user's privilege level? Thanks in advance.
Upvotes: 1
Views: 1014
Reputation: 93044
Instead of mov rax,cr0
, you can use the smsw
instruction to store the low 16 bit of cr0
. This instruction is not privileged and works on all rings:
smsw ax
test ax,1
jnz protected_mode
Upvotes: 3
Reputation: 76617
You are trying to execute a privileged instruction whilst you are not in a privileged mode.
According to the instruction set reference:
Protected Mode Exceptions
#GP(0) If the current privilege level is not 0.
Because you are running in user mode you cannot run privileged instructions.
In order to enter real mode you must first get a privilege level in ring 0.
In order for this to happen you must be executing in kernel mode.
See fuz's answer on how to do this in Linux.
For more info on entering and exiting real mode see: https://www.codeproject.com/articles/45788/the-real-protected-long-mode-assembly-tutorial-for
Upvotes: 1