Search code examples
assemblyoperating-systembootshutdown

How can shutdown the PC with Assembly 16 bits in boot mode?


I wrote a small bootloader that i write in a Diskette, the bootloader is working fine, i write a function to reboot the PC, but i can't shutdown the PC, i try a lot but i've just got an infinite beep song from the speaker. I'm in boot mode, so windows interruptions doesn't work. How can i do it? I'm compiling with NASM and write in diskette with Rawriter.

I had tried a code that i see here in Stackoverflow, but it doesn't works.

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

And i tried that another too

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

Solution

  • How far you do want to go with this?

    Because shutting down a computer is chipset specific, the hardware programming interface has never been standardized.
    However a software interface has been standardized, actually two have been: Advanced Power Management (APM) and Advanced Configuration And Power Interface (ACPI).

    While the first is really easy and it is the one you are using, it is very very old (in computer industry years). I have made a simple boot program that use APM to shutdown the computer. It does all the things pedantically in the proper way.
    With Bochs it works. On real hardware (tested on 3 laptops) it doesn't and prints the error code A which means No APM service found.
    This seems to suggest that the APM interface is no longer supported, this didn't surprise me to be honest I was expecting it and the converse would have.

    So you are left with the ACPI, now unless you are really familiar with it I simply suggest you to not dig into that (rather if your is a specific solution get your chipset datasheet) as it is quite elaborate, and has specific terminology and it handle the whole aspect of power management.
    You would have to find and parse various tables, interpret AML code sequences, setup a proper environment, it will take a long long time.

    The closest thing to a shutdown without APM or ACPI is the well known

    cli
    hlt
    

    instruction pair.

    If you are interested in the APM boot program to give it a try, here it is

    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