我需要编写一个代码来测试nasm中cr0
的LSB。代码如下:
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
代码在运行时会导致分段错误。它的发生是由于指令mov rax,cr0
。注释该指令时,不会发生分段错误。为什么会这样?这与用户的权限级别有关吗?提前谢谢。
代替 mov rax,cr0
,您可以使用 smsw
指令来存储低 16 位的cr0
。此指令不是特权,适用于所有环:
smsw ax
test ax,1
jnz protected_mode
您正在尝试在不处于特权模式的情况下执行特权指令。
根据指令集参考:
保护模式例外
#GP(0) 如果当前权限级别不为 0。
由于在用户模式下运行,因此无法运行特权指令。
为了进入实模式,您必须首先在环 0 中获得权限级别。
为此,您必须在内核模式下执行。
请参阅fuz关于如何在Linux中执行此操作的答案。
有关进入和退出实模式的详细信息,请参阅:https://www.codeproject.com/articles/45788/the-real-protected-long-mode-assembly-tutorial-for