为什么mov rax,cr0在nasm 64位

时间:2017-01-29 14:36:58

标签: assembly 64-bit nasm sigsegv

我需要编写一个代码来测试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指令而发生的。当评论该指令时,不会发生分段错误。为什么会这样?这与用户的权限级别有关吗?提前谢谢。

2 个答案:

答案 0 :(得分:2)

您可以使用smsw instruction来存储mov rax,cr0的低16位,而不是cr0。该指令不具有特权,适用于所有环:

smsw ax
test ax,1
jnz protected_mode

答案 1 :(得分:1)

您正在尝试在未处于特权模式时执行特权指令 根据{{​​3}}

  

保护模式例外
  #GP(0)   如果当前权限级别不为0.

因为您在用户模式下运行,所以无法运行特权指令。

要进入实模式,您必须首先获得第0环的特权级别。
为了实现这一点,您必须在内核模式下执行 有关如何在Linux中执行此操作,请参阅instruction set reference:

有关进入和退出实模式的详细信息,请参阅:fuz's answer