intel系统指令如何在linux上运行?

Can*_*niz 1 linux x86 assembly segmentation-fault

使用第 7 代 i5 处理器,nasm,ld。

该程序使用通用寄存器和系统调用编写,可在 Ubuntu 上运行。一个例子是一个简单的 hello world 程序。

global _start


section .text
    _start:

        mov eax, 0x4                ; write(int fd, char *buf, int len)
        mov ebx, 0x1                ; fd
        mov ecx, message            ; *buf
        mov edx, message_length     ; len
        int 0x80                    ; syscall

        mov eax, 0x1                ; exit(int status)
        mov ebx, 0x0                ; status
        int 0x80                    ; syscall
    



section .data
    message db "hello world", 0xA
    message_length equ $-message
Run Code Online (Sandbox Code Playgroud)
nasm -f elf64 -o hello_world.o hello_world.s
ld hello_world.o -o hello_world
./hello_world
Run Code Online (Sandbox Code Playgroud)

输出: hello_world

但是,使用intel 系统指令编写的程序不起作用。

global _start



section .text
    _start:
        CLI
        HLT
Run Code Online (Sandbox Code Playgroud)
nasm -f elf64 halt.s -o halt.o
ld halt.o -o halt
./halt
Run Code Online (Sandbox Code Playgroud)

输出: Segmentation fault (core dumped)

  1. 是什么阻止了这段代码以这种方式编译和运行?
  2. 这段代码如何编译和运行?

zx4*_*485 5

你有两个问题:

  1. 是什么阻止了这段代码以这种方式编译和运行?

    没有什么可以阻止它组装,因为它是有效的代码。
    其原因不运行/抛出一个segmentation fault的是,你正试图运行需要在用户模式下某些特权指令。

    看看描述说明的HLT

    HLT 指令是特权指令。

    也看看CLI /STI,它的情况更复杂(在下面的文章和下面的评论中解释),但也主要用于内核模式代码。维基百科

    在所有三种情况下,只有特权应用程序(通常是操作系统内核)可以修改 IF[Interrupt flag]。[...] CLI 和 STI [也是] 特权指令,如果非特权应用程序尝试执行它,则会触发一般保护错误,[...]

    这应该可以回答您关于这两条指令之间的区别以及为什么HLT肯定会生成在User Mode 中执行的 GPF (General Protection Fault) 的问题。

  2. 这段代码如何编译和运行?

    运行此代码的唯一方法是在特权模式下。因此,在 Windows 或 Linux 上,您必须编写内核驱动程序或编写自己的操作系统代码才能合理使用这些指令。

以上仅适用于保护模式长模式代码。
(实模式代码可能总是修改 IF,中断标志

  • Linux下的特权用户可以调用函数“iopl”并将其设置为3,然后可以使用“CLI”和“STI”https://man7.org/linux/man-pages/man2/iopl.2.html 。不过,“HLT”不受 IOPL 影响,并且如果 CPL != 0,则会提高 #GP。 (3认同)
  • Linux 为您提供了“iopl()”。不过,这对 HLT 不起作用。 (2认同)