Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

X86 instructions to power off computer in real mode?

Is there any sequence of x86 instructions in real mode that will power off (not reboot) the machine? I have an old computer with MS-DOS still on it and I'm curious about it.

This question is specifically about real mode, not protected mode or 64-bit long mode.

like image 982
Govind Parmar Avatar asked Jan 30 '14 17:01

Govind Parmar


1 Answers

From this article on OSDev, you can either use the ACPI or the APM interfaces. ACPI seems overcomplicated, as you can see in this article while APM is much simpler. I'll report the basic steps as they appear here:

1) Installation check, to see if APM is supported:

mov ah,53h            ;this is an APM command
mov al,00h            ;installation check command
xor bx,bx             ;device id (0 = APM BIOS)
int 15h               ;call the BIOS function through interrupt 15h
jc APM_error          ;if the carry flag is set there was an error
                      ;the function was successful
                      ;AX = APM version number
                          ;AH = Major revision number (in BCD format)
                          ;AL = Minor revision number (also BCD format)
                      ;BX = ASCII characters "P" (in BH) and "M" (in BL)
                      ;CX = APM flags (see the official documentation for more details)

2) Disconnect to any existing interface:

;disconnect from any APM interface
mov ah,53h               ;this is an APM command
mov al,04h               ;interface disconnect command
xor bx,bx                ;device id (0 = APM BIOS)
int 15h                  ;call the BIOS function through interrupt 15h
jc .disconnect_error            ;if the carry flag is set see what the fuss is about. 
jmp .no_error

.disconnect_error:       ;the error code is in ah.
cmp ah,03h               ;if the error code is anything but 03h there was an error.
jne APM_error            ;the error code 03h means that no interface was connected in the first place.

.no_error:
                         ;the function was successful
                         ;Nothing is returned.

3) Connect to the real mode interface (01h):

;connect to an APM interface
mov ah,53h               ;this is an APM command
mov al,[interface_number];see above description
xor bx,bx                ;device id (0 = APM BIOS)
int 15h                  ;call the BIOS function through interrupt 15h
jc APM_error             ;if the carry flag is set there was an error
                         ;the function was successful
                         ;The return values are different for each interface.
                         ;The Real Mode Interface returns nothing.
                         ;See the official documentation for the 
                         ;return values for the protected mode interfaces.

4) Enable power management for all devices:

;Enable power management for all devices
mov ah,53h              ;this is an APM command
mov al,08h              ;Change the state of power management...
mov bx,0001h            ;...on all devices to...
mov cx,0001h            ;...power management on.
int 15h                 ;call the BIOS function through interrupt 15h
jc APM_error            ;if the carry flag is set there was an error

5) Finally, set the power state to off (03h):

;Set the power state for all devices
mov ah,53h              ;this is an APM command
mov al,07h              ;Set the power state...
mov bx,0001h            ;...on all devices to...
mov cx,[power_state]    ;see above
int 15h                 ;call the BIOS function through interrupt 15h
jc APM_error            ;if the carry flag is set there was an error
like image 95
BlackBear Avatar answered Sep 27 '22 18:09

BlackBear