问题 如何关机?我正在构建一个我自己的小操作系统[重复]


这个问题在这里已有答案:


10237
2018-01-15 03:37


起源

什么平台?请标记您的问题...... - Oliver Charlesworth
x86基于英特尔 - manuhg
为什么它最近变得如此受欢迎发布一个 图片 你的代码?这比复制和粘贴更容易吗?当然你知道如何复制和粘贴...... - Cody Gray♦


答案:


hlt 指令停止x86直到发生中断。除非禁用所有中断,否则将使处理器停止大约一毫秒左右。

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


10
2018-01-15 04:18



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


停止指令不会关闭电源。 它使处理器进入非执行状态。
通常,您可以在处理器复位后退出暂停状态。
在某些微控制器中,特定中断也可使处理器退出暂停状态。 断电是主板/ BIOS特定操作。


1
2018-01-15 03:45



那么请告诉我怎么称呼它。我想知道的是如何关闭我的操作系统和我的电脑 - manuhg
@alvin:在x86上,每个中断都会使处理器退出hlt状态。在处理器处于hlt状态时,以任何方式转动计算机都不比在运行时更安全,因为所有磁盘缓冲区等都不会被刷新。 - Gunther Piez
@drhirsch,你是对的,没想到操作系统状态。编辑了我的答案。 - alvin


通过使用这两行代码:

    cli                     ; stop all interrupts
    hlt                     ; halt the cpu

你可以暂停x86 pc的可启动程序:

    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”指令。正如迈克尔所提到的,有必要确保从左到右加载text_string。


0
2018-04-07 15:11



当然无限循环应该包括 cli / hlt,如果NMI到达。我的意思是,如果你将要有一个无限循环......但无论如何,这并没有回答这个问题。这样可以使CPU处于低功耗空闲状态,而不是关闭状态。 - Peter Cordes
这不会关闭计算机,它只会停止它。 - Ross Ridge
除了罗斯和彼得提到的非常有效和相关(关于停止/关闭的问题)之外,我将指出(在一般的引导程序的上下文中)你的代码做出错误的假设,即BIOS清除了方向在它到达你的引导程序之前的标志。你真的应该打电话 CLD 因为你最终使用 lodsb 。 - Michael Petch