如何关闭计算机?我正在构建自己的微型操作系统。

11

汇编中的hlt指令能否关闭计算机,因为它会停止处理器?如果可以使用我所说的方法进行操作,这是否正确?

hlt指令能否关闭计算机?

start:
    xor ax, ax; ;clear ax
    mov bx, ax; ;clear bx
    cli ;stop all interrupts
    hlt ;halt the cpu

如果这不是正确的方法,或者这样做无法关闭系统,请告诉我正确的方法。


1
什么平台?请标记您的问题... - Oliver Charlesworth
14
最近为什么晒自己的代码截图这么流行?相较于复制粘贴,这样做有何便利之处?你肯定知道怎么复制粘贴吧… - Cody Gray
3个回答

10
< p > hlt 指令会暂停x86直到发生中断。除非禁用所有中断,否则处理器只会停止一毫秒左右。

要关闭现代计算机,请使用 ACPI(高级配置和电源接口)


谢谢。但我找不到如何设置全局电源状态。我能得到一些帮助吗? - manuhg
6
实现ACPI接口对于一个“微型操作系统”来说并不是易事。如果你使用的是BIOS仍然实现了APM的较旧计算机,你可以通过关闭APM来解决关机问题(http://en.wikipedia.org/wiki/Advanced_Power_Management),这就是Windows 95的做法。请注意,在此之前的操作系统,如DOS,无法关闭计算机。 - Gunther Piez

1
通过使用这两行代码:

    cli                     ; stop all interrupts
    hlt                     ; halt the cpu

你可以暂停一个适用于x86个人电脑的可启动程序:

    BITS 16

start:
    mov ax, 07C0h           ; Set up 4K stack space after this bootloader
    add ax, 288             ; (4096 + 512) / 16 bytes per paragraph
    mov ss, ax
    mov sp, 4096

    mov ax, 07C0h           ; Set data segment to where we're loaded
    mov ds, ax


    cld                     ; clear direction flag
    mov si, text_string     ; Put string position into SI
    call print_string       ; Call our string-printing routine


    cli                     ; stop all interrupts
    hlt                     ; halt the cpu

    jmp $                   ; Jump here - infinite loop!


    text_string db 'Hello World!', 0


print_string:               ; Routine: output string in SI to screen
    mov ah, 0Eh             ; int 10h 'print char' function

.repeat:
    lodsb                   ; Get character from string
    cmp al, 0
        je .done            ; If char is zero, end of string
    int 10h                 ; Otherwise, print it
    jmp .repeat

.done:
    ret


    times 510-($-$$) db 0   ; Pad remainder of boot sector with 0s
    dw 0xAA55               ; The standard PC boot signature

将其保存为"prog.asm",然后使用"nasm"创建引导扇区:

nasm -f bin -o boot.img prog.asm

现在你可以使用“qemu”来测试它:
qemu-system-i386 -drive file=boot.img,index=0,media=disk,format=raw -boot c -net none

注意:移除上述两行会导致您的虚拟机使用所有可用的CPU周期。
编辑:添加了“cld”指令。正如Michael所提到的,有必要确保text_string从左到右加载。

2
无疑,无限循环应该包括 cli / hlt,以防 NMI 到达。我的意思是,如果你要有一个无限循环...但无论如何,这并没有回答问题。这只是让 CPU 保持低功耗空闲状态,而不是关闭。 - Peter Cordes
4
这并不会关机电脑,它仅仅是停止了它。 - Ross Ridge
3
除了Ross和Peter提到的关于停止/关闭的非常合理和相关的内容之外,我还要指出(就引导加载程序而言),你的代码存在错误的假设,即BIOS在到达引导加载程序之前已经清除了方向标志。由于你最终使用了 lodsb,因此你真的应该调用 CLD - Michael Petch

1

halt指令并不会关闭电源,而是将处理器置于非执行状态。
通常情况下,你可以通过处理器重置来退出halt状态。
在一些微控制器中,特定的中断也可以将处理器从halt状态中唤醒。 关闭电源是一个主板/BIOS特定的操作。


请告诉我如何调用它。我想知道如何关闭我的操作系统和计算机。 - manuhg
3
在 x86 架构中,每个中断都会将处理器从 HLT 状态中唤醒。在处理器处于 HLT 状态时关机并不比在其运行时更加安全,因为所有磁盘缓存等都没有被刷新。请注意,此翻译仅供参考,不得用于正式文件或场合。 - Gunther Piez
@drhirsch,你说得对,我没有考虑到操作系统的状态。我已经编辑了我的回答。 - alvin

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接