assembly - 如何在引导模式下关闭具有 Assembly 16 位的 PC?

标签 assembly operating-system boot shutdown

我写了一个小的引导加载程序,我写在软盘中,引导加载程序工作正常,我编写了一个重新启动电脑的功能,但我无法关闭电脑,我尝试了很多,但我刚刚得到了一个扬声器发出无限的蜂鸣声。我处于启动模式,因此 Windows 中断不起作用。我该怎么做?我用 NASM 编译并用 Rawriter 写入软盘。

我尝试过在 Stackoverflow 中看到的代码,但它不起作用。

MOV     AX,5307
MOV     BX,0001
MOV     CX,0003
INT     15

我也尝试了另一个

   mov ax, 0x1000
    mov ax, ss
    mov sp, 0xf000
    mov ax, 0x5307
    mov bx, 0x0001
    mov cx, 0x0003
    int 0x15

最佳答案

您想做到什么程度?

由于关闭计算机是芯片组特定的,因此硬件编程接口(interface)从未标准化。
然而软件接口(interface)已经标准化,实际上有两个:Advanced Power Management (APM)Advanced Configuration And Power Interface (ACPI) .

虽然第一个非常简单,而且也是您正在使用的,但它非常非常古老(在计算机行业的年代)。我制作了一个简单的启动程序,使用APM来关闭计算机。它以正确的方式迂腐地完成所有事情。
有了博赫斯,它就起作用了。在真实硬件上(在 3 台笔记本电脑上测试),它不会并打印错误代码 A,这意味着未找到 APM 服务
这似乎表明不再支持 APM 接口(interface),老实说,这并不令我感到惊讶,我早在预料之中,反之亦然。

所以你只剩下ACPI,现在除非你真的熟悉它,否则我只是建议你不要深入研究它(如果你是一个特定的解决方案,请获取你的芯片组数据表),因为它相当详尽,并且有特定的术语,它处理电源管理的整个方面。
你必须查找并解析各种表,解释 AML 代码序列,设置合适的环境,这将需要很长很长的时间。

在没有APMACPI的情况下最接近关闭的是众所周知的

cli
hlt

指令对。

如果您对 APM 启动程序感兴趣并尝试一下,这里就是

BITS 16
jmp 07c0h:WORD __START__

__START__:
  mov ax, cs
  mov ss, ax
  xor sp, sp
  push cs
  pop ds
  push WORD 0b800h
  pop es

  mov ax, 03h
  int 10h



  ;^   ^   ^   ^   ^   ^   ^   ^   ^   ^   ^   ^   ^   ^   ^   ^   ^     
  ; \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \
  ;  v   v   v   v   v   v   v   v   v   v   v   v   v   v   v   v   v

  ;Check APM service is present
  mov BYTE [error], 'A'  

  mov ax, 5300h
  xor bx, bx
  int 15h
  jc .err
  inc BYTE [error]
  cmp bx, 504dh
  jne .err

  ;^   ^   ^   ^   ^   ^   ^   ^   ^   ^   ^   ^   ^   ^   ^   ^   ^     
  ; \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \
  ;  v   v   v   v   v   v   v   v   v   v   v   v   v   v   v   v   v

  ;Connect RM interface, compatibility mode APM 1.0
  inc BYTE [error]

  mov ax, 5301h
  xor bx, bx
  int 15h
  jc .err

  ;^   ^   ^   ^   ^   ^   ^   ^   ^   ^   ^   ^   ^   ^   ^   ^   ^     
  ; \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \
  ;  v   v   v   v   v   v   v   v   v   v   v   v   v   v   v   v   v

  ;Switch to APM 1.1+
  inc BYTE [error]

  mov ax, 530eh
  xor bx, bx
  mov cx, 0101h
  int 15h
  jc .err
  inc BYTE [error]
  cmp al, 01h
  jb .err

  ;^   ^   ^   ^   ^   ^   ^   ^   ^   ^   ^   ^   ^   ^   ^   ^   ^     
  ; \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \
  ;  v   v   v   v   v   v   v   v   v   v   v   v   v   v   v   v   v

  ;Enable APM
  inc BYTE [error]

  mov ax, 5308h
  mov bx, 01h
  mov cx, 01h
  int 15h
  jc .err

  ;^   ^   ^   ^   ^   ^   ^   ^   ^   ^   ^   ^   ^   ^   ^   ^   ^     
  ; \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \
  ;  v   v   v   v   v   v   v   v   v   v   v   v   v   v   v   v   v

  ;Engage APM
  inc BYTE [error]

  mov ax, 530fh
  mov bx, 01h
  mov cx, 01h
  int 15h
  jc .err

  ;^   ^   ^   ^   ^   ^   ^   ^   ^   ^   ^   ^   ^   ^   ^   ^   ^     
  ; \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \
  ;  v   v   v   v   v   v   v   v   v   v   v   v   v   v   v   v   v

  ;Shutdown
  inc BYTE [error]

  mov ax, 5307h
  mov bx, 01h
  mov cx, 03h
  int 15h
  jc .err

jmp .end 

.err:
  xor di, di
  mov ah, 09h
  mov al, BYTE [error]
  stosw

.end:
  cli
  hlt

  error db 0

  TIMES 505-($-__START__) db 0
  dw 0aa55h

关于assembly - 如何在引导模式下关闭具有 Assembly 16 位的 PC?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31150615/

相关文章:

c++ - 调用但不跳转到 rax 中的地址时出现段错误

go - 如何使用汇编优化这个 8 位位置 popcount?

python os.rename模块删除文件

从 XP 切换到 WIN2K 时出现 Java 异常

c++ - 如何使用 Boost 解析超过 2 级的 ini 文件

c++ - 将 32 位浮点转换为 IEEE 80 位

c - C 中的内联汇编 - 了解编译结果

operating-system - 直接连接到 CPU 的 PCIe 插槽的中断路由

php - 启动时启动 PHP 命令行

c - 无操作系统执行