为什么 mov rax,cr0 会导致 nasm 64 位的分段错误



我需要编写一个代码来测试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

相关内容

  • 没有找到相关文章

最新更新