.Model tiny
.Code
Org 100h
Start:
mov ax,5300h
xor bx,bx
int 15h ; Check APM install
jnb @@1
jmp ExitSys
@@1:
cmp bx,504Dh ; sign
jz @@2
jmp ExitSys
@@2:
cmp ax,101h ; ver 1.1
jnb @@3
jmp ExitSys
@@3:
push cx
mov Version,ax
mov ax,5400h
xor bx,bx
int 2Fh ; power.exe install check?
xor ax,ax
cmp bx,504Dh
jnz @@4
push ax ; power.exe version
mov ax,5401h
mov bx,100h
int 2Fh ; set management enable
pop ax
jb @@4
inc ax
@@4:
pop cx
push ax
push bx
push cx
mov ax,5301h
xor bx,bx
int 15h ; real-mode interface
mov ax,530Eh
xor bx,bx
mov cx,101h
int 15h ; driver version
mov ax,530Fh
mov bx,1
mov cx,bx
int 15h ; engage power management
mov ax,5308h
mov bx,1
mov cx,bx
int 15h ; enable power mamagement
mov ax,5307h
mov bx,1
mov cx,3
int 15h ; power off
pop cx ; support device
test cl,8 ; BIOS power management disable?
jz @@5
push cx
mov ax,5308h
mov bx,1
xor cx,cx
int 15h ; system stand-by
pop cx
@@5:
test cl,10h ; BIOS power disengaged
jz @@6
mov ax,530Fh
mov bx,1
xor cx,cx
int 15h ; disengage power management
@@6:
mov ax,5304h
xor bx,bx
int 15h ; disconnect interface
pop bx
pop ax
test ax,ax
jz ExitSys
mov ax,5401h
mov bl,bh
mov bh,1
int 2Fh ; set APM firmware power manager enable
ExitSys:
mov ax,4c00h
int 21h
Version DW ?
End Start
.Code
Org 100h
Start:
mov ax,5300h
xor bx,bx
int 15h ; Check APM install
jnb @@1
jmp ExitSys
@@1:
cmp bx,504Dh ; sign
jz @@2
jmp ExitSys
@@2:
cmp ax,101h ; ver 1.1
jnb @@3
jmp ExitSys
@@3:
push cx
mov Version,ax
mov ax,5400h
xor bx,bx
int 2Fh ; power.exe install check?
xor ax,ax
cmp bx,504Dh
jnz @@4
push ax ; power.exe version
mov ax,5401h
mov bx,100h
int 2Fh ; set management enable
pop ax
jb @@4
inc ax
@@4:
pop cx
push ax
push bx
push cx
mov ax,5301h
xor bx,bx
int 15h ; real-mode interface
mov ax,530Eh
xor bx,bx
mov cx,101h
int 15h ; driver version
mov ax,530Fh
mov bx,1
mov cx,bx
int 15h ; engage power management
mov ax,5308h
mov bx,1
mov cx,bx
int 15h ; enable power mamagement
mov ax,5307h
mov bx,1
mov cx,3
int 15h ; power off
pop cx ; support device
test cl,8 ; BIOS power management disable?
jz @@5
push cx
mov ax,5308h
mov bx,1
xor cx,cx
int 15h ; system stand-by
pop cx
@@5:
test cl,10h ; BIOS power disengaged
jz @@6
mov ax,530Fh
mov bx,1
xor cx,cx
int 15h ; disengage power management
@@6:
mov ax,5304h
xor bx,bx
int 15h ; disconnect interface
pop bx
pop ax
test ax,ax
jz ExitSys
mov ax,5401h
mov bl,bh
mov bh,1
int 2Fh ; set APM firmware power manager enable
ExitSys:
mov ax,4c00h
int 21h
Version DW ?
End Start
Gemini 解答
这段汇编代码是一个典型的 16 位 DOS COM 程序,旨在通过调用 APM(Advanced Power Management,高级电源管理)BIOS 中断规范来实现主机软关机(Power Off)。
1. 核心流程与 APM 规范机制
在 ACPI 普及之前(ATX 电源早期及 Windows 95/98 时代),PC 平台的电源管理主要依赖 APM 规范(标准调用入口为
INT 15h, AX=53xxh)。该程序按照标准的 APM 状态机步骤执行:
- APM 安装检查与版本确认(
INT 15h, AX=5300h):
- 检查系统是否支持 APM,若支持,BIOS 会清除进位标志(CF=0),并在
BX中返回特征签名504Dh(ASCII 码的'PM'),在AX中返回 BCD 编码的 APM 版本号。- 程序要求版本必须大于或等于 1.1(
AX >= 0101h),因为 APM 1.0 不支持关机(Power Off)状态码。- POWER.EXE 状态检测与处理(
INT 2Fh, AX=5400h):
- 检测 MS-DOS 自带的 APM 驱动
POWER.EXE是否已加载,若已加载则先调整其管理状态,避免后续直接调用 BIOS 时产生冲突。- 建立实模式接口连接(
INT 15h, AX=5301h):
- 告诉 APM BIOS 当前程序将以实模式(Real Mode)方式进行电源管理调用。
- 设置驱动版本(
INT 15h, AX=530Eh):
- 将驱动连接版本显式指定为 APM 1.1(
CX=0101h)。- 接管与启用电源管理(
INT 15h, AX=530Fh/AX=5308h):
BX=0001h表示操作对象为“所有设备(All Devices)”。- 先通过
530Fh, CX=1启用对电源状态的控制(Engage),再通过5308h, CX=1启用电源管理功能(Enable)。- 执行关机(
INT 15h, AX=5307h):
BX=0001h(所有设备),CX=0003h(状态:Power Off)。- 在支持 ATX 软断电的正常硬件上,BIOS 处理该中断后会直接向南桥芯片或电源管理控制器发送断电信号,机器在执行到这条指令时便会立即切断电源。
- 失败回退与清理逻辑(
@@5之后):
- 如果关机失败(硬件不支持软关机或 BIOS 拒绝执行),CPU 会继续执行后续指令:依次尝试挂起/恢复状态、断开 APM 连接(
INT 15h, AX=5304h),最后返回 DOS。
2. 代码中的设计缺陷与潜在隐患
虽然逻辑框架完整,但代码存在几处细节问题:
- 磁盘缓存未刷新(最严重隐患): 在 DOS 环境下,如果系统加载了写延迟缓存工具(如
SMARTDRV.EXE),直接调用硬件断电会导致滞留在内存中的脏数据丢失,引发文件系统损坏。标准做法应在关机调用前,通过 DOS 复位驱动器(INT 21h, AH=0Dh)或调用 SmartDrive 的刷新接口(INT 2Fh, AX=4A10h, BX=0001h)强制刷盘。- 寄存器堆栈平衡混乱: 在执行
INT 15h, AX=5307h之前,程序执行了三次push(ax,bx,cx)。在关机调用之后立即执行了pop cx,但在随后的@@5条件分支中,push cx与pop cx位于跳转分支内部,若条件不满足跳过push cx,会导致后续的栈指针(SP)错位,最终引发崩溃或无法正常返回 DOS。- 错误检测缺失: 中间所有的
INT 15h功能调用均未对返回的进位标志(CF)进行校验。如果其中某一步骤失败(例如接口已被其他程序占用),后续的调用可能全部无效。
3. 运行环境与兼容性边界
- AT 架构老机器:老式的 AT 电源使用的是物理自锁式机械开关,主板没有软断电电路,调用该程序只能使系统处于挂起/降频状态,无法实现切断电源。
- ATX 架构(Pentium II 至 Pentium 4 早期):标准支持 APM 1.1/1.2,在纯 DOS 或 Windows 98 纯 DOS 模式下可以完美切断主机电源。
- 现代 UEFI / ACPI 机器及虚拟机: 现代 PC 的 BIOS 大多已经彻底移除了 APM 实模式接口,全面转用 ACPI;在部分虚拟机(如较新版本的 VMware / VirtualBox 或 DOSBox 默认配置)中,APM 中断可能未被模拟或默认禁用,会导致程序在首个版本检测处直接退出,无法执行关机。
ko20010214
=================================
大功告成,打个Kiss!
ko20010214@MSN.com
神州优雅Q300C
Intel CeleronM 370处理器 | 256MbDDR内存
40G硬盘 | USB2.0 | IEEE 1394
13.3 ' WXGA 宽屏(16:10) | COMBO光驱
10/100M网卡 | 四合一读卡器
=================================
大功告成,打个Kiss!
ko20010214@MSN.com
神州优雅Q300C
Intel CeleronM 370处理器 | 256MbDDR内存
40G硬盘 | USB2.0 | IEEE 1394
13.3 ' WXGA 宽屏(16:10) | COMBO光驱
10/100M网卡 | 四合一读卡器


