使用组件关闭计算机

15 assembly shutdown

如何仅使用汇编代码关闭计算机?

use*_*876 10

您需要说明它是什么处理器系列以及您正在使用的操作系统.还有你的代码运行的特权 - 如果它是内核代码,那么它拥有比用户代码更多的特权.

假设您在Intel x86系列CPU上使用Windows NT系列的某些成员(包括XP或Vista),并且您的代码是正常(用户空间)代码,那么......您需要调用Windows内置函数做这个.你不能只执行一些神奇的装配序列.

即使您可以执行一些神奇的汇编序列,您也不会想要 - 您几乎肯定希望让操作系统有机会将数据从磁盘缓存写入磁盘,并执行其他优雅关闭的操作.

如果您正在为x86编写自己的操作系统,那么您需要查看ACPI(或APM)规范.如果GPL代码没问题,那么相关的Linux内核例程就在这里(ACPI)这里(APM).


Syn*_*ech 9

这是我用来在DOS模式下关闭电脑多年的29字节程序.

;Connect to APM API
MOV     AX,5301
XOR     BX,BX
INT     15

;Try to set APM version (to 1.2)
MOV     AX,530E
XOR     BX,BX
MOV     CX,0102
INT     15

;Turn off the system
MOV     AX,5307
MOV     BX,0001
MOV     CX,0003
INT     15

;Exit (for good measure and in case of failure)
RET
Run Code Online (Sandbox Code Playgroud)

您可以在DJGPP使用Ralf Brown的中断列表查找更多功能.


小智 7

在Linux中读取reboot(2).

来源文件:

kernel/sys.c kernel/exit.c和arch/x86/kernel/apm.c

不是一个完整的答案,但我认为这是一个良好的开端.我将不得不阅读我的BIOS机器代码,看看他们做了什么.但这部分是机器特定的.如果您知道主板上的IC控制电源,您可以找出所需的IO端口,寄存器和命令.然后设置正确的板/设备状态,然后发出命令关闭电源.

BIOS通过INT 15h ah = 53h管理电源(所谓的高级电源管理又称APM)函数al = 07在Linux中使用的是设置电源状态cmd.参数bx = 0001h表示所有设备,cx = 0003k表示停止.


小智 5

来自 arch/x86/kernel/amp.c:

/**
 * apm_power_off - ask the BIOS to power off
 *
 * Handle the power off sequence. This is the one piece of code we
 * will execute even on SMP machines. In order to deal with BIOS
 * bugs we support real mode APM BIOS power off calls. We also make
 * the SMP call on CPU0 as some systems will only honour this call
 * on their first cpu.
 */

static void apm_power_off(void)
{
 unsigned char po_bios_call[] = {
  0xb8, 0x00, 0x10, /* movw  $0x1000,ax  */
  0x8e, 0xd0,  /* movw  ax,ss       */
  0xbc, 0x00, 0xf0, /* movw  $0xf000,sp  */
  0xb8, 0x07, 0x53, /* movw  $0x5307,ax  */
  0xbb, 0x01, 0x00, /* movw  $0x0001,bx  */
  0xb9, 0x03, 0x00, /* movw  $0x0003,cx  */
  0xcd, 0x15  /* int   $0x15       */
 };

 /* Some bioses don't like being called from CPU != 0 */
 if (apm_info.realmode_power_off) {
  set_cpus_allowed_ptr(current, cpumask_of(0));
  machine_real_restart(po_bios_call, sizeof(po_bios_call));
 } else {
  (void)set_system_power_state(APM_STATE_OFF);
 }
}
Run Code Online (Sandbox Code Playgroud)

代码现在在apm_32.c 中。搜索“apm_power_off”。


tjb*_*tjb 5

将上面的@larz 答案转换为 nasm 程序集的操作如下:

先决条件:Bochs、Nasm

这个例子是在带有标准包的 debian wheezy 上运行的。

代码(文件名:shutdown.asm):

    org 0x7c00
    jmp main

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

WaitForEnter:
    mov ah, 0
    int 0x16
    cmp al, 0x0D
    jne WaitForEnter
    ret

main:   
    call WaitForEnter
    call Shutdown

times 510-($-$$) db 0
dw 0xaa55
Run Code Online (Sandbox Code Playgroud)

Nasm 汇编:

nasm -f bin -o boot_sect.img shutdown.asm
Run Code Online (Sandbox Code Playgroud)

Bochs 配置文件(文件名:.bochsrc)与代码(shutdown.asm)在同一目录

display_library: sdl
floppya: 1_44=boot_sect.img, status=inserted
boot: a
Run Code Online (Sandbox Code Playgroud)

*注意我正在使用 bochs 的 sdl 库,它是与 bochs 本身分开的一个包

运行 bochs(来自与之前相同的目录):

bochs
Run Code Online (Sandbox Code Playgroud)

按回车关机

*注意我不确定 Shutdown 标签和 WaitForEnter 标签之间的所有行都是必需的


And*_*ant 1

调用kernel32.dll中的ExitWindowsEx API函数