Apague la computadora usando ensamblaje

¿Cómo puedo apagar la computadora usando solo el código de ensamblaje?

Debe decir qué familia de procesadores es y qué sistema operativo está utilizando. Además, con qué privilegios se ejecuta su código: si se trata de un código de kernel, tiene más privilegios que el código de usuario.

Suponiendo que está utilizando algún miembro de la familia Windows NT (incluido XP o Vista) en una CPU de la familia Intel x86, y su código es código normal (espacio de usuario), entonces … debe llamar a la función incorporada de Windows para hacer esto. No puedes simplemente ejecutar alguna secuencia mágica de ensamblaje.

Incluso si pudieras simplemente ejecutar alguna secuencia mágica de ensamblaje, no querrías, casi seguramente querrás darle al sistema operativo la oportunidad de escribir datos desde la memoria caché de disco en el disco, y hacer otras cosas elegantes de apagado.

Si está escribiendo su propio sistema operativo para x86, entonces necesita ver las especificaciones ACPI (o APM). Si el código GPL es correcto, entonces las rutinas pertinentes del kernel de Linux están aquí (ACPI) y aquí (APM) .

Este es el progtwig de 29 bytes que he estado usando para apagar la computadora en modo DOS por años.

;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 

Puede buscar más funciones con la lista de interrupción de Ralf Brown en DJGPP .

En Linux lee reiniciar (2).

fonts de archivos de interés:

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

no es una respuesta completa, pero creo que es un buen comienzo. Tendré que leer el código de mi máquina BIOS para ver qué hacen. pero esta parte es específica de la máquina. Si sabe qué potencia de control de IC en su placa base puede averiguar qué puerto de E / S, registrar y ordenar necesita. luego configure los estados apropiados de la placa / dispositivo y luego emita el comando para apagar la unidad.

BIOS gestiona la potencia a través de INT 15h ah = 53h (llamada función de gestión de energía avanzada también conocida como APM) función al = 07 utilizada en Linux es el estado de energía establecido cmd. los parámetros bx = 0001h significan todos los dispositivos y cx = 0003k significa parada.

Desde 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); } } 

El código ahora está en apm_32.c . Busque “apm_power_off”.

La conversión de la respuesta @larz anterior al ensamblaje nasm se realiza de la siguiente manera:

Prerrequisitos: Bochs, Nasm

Este ejemplo se ejecutó en debian wheezy con paquetes estándar.

Código (nombre de archivo: 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 

Comstackción de Nasm:

 nasm -f bin -o boot_sect.img shutdown.asm 

Archivo de configuración de Bochs (nombre de archivo: .bochsrc) en el mismo directorio que el código (shutdown.asm)

 display_library: sdl floppya: 1_44=boot_sect.img, status=inserted boot: a 

* Nota. Estoy usando la biblioteca sdl para Bochs, que es un paquete separado de Bochs.

Ejecutando bochs (del mismo directorio que antes):

 bochs 

Presiona enter para cerrar

* Nota: no estoy seguro de que todas las líneas entre la etiqueta Shutdown y la etiqueta WaitForEnter sean necesarias

Es bastante fácil. Además, chicos, OP podría estar trabajando en su propio administrador de energía. Lo mismo que estoy haciendo exactamente. Este es un ejemplo que permitirá al usuario apagar la máquina. Muy simple, simplemente le da al usuario un cuadro de mensaje con Aceptar y Cancelar. Si el usuario pulsa OK, la máquina se apagará, si el usuario pulsa cancelar, el progtwig simplemente saldrá. Se prueba en las versiones de Windows basadas en NT, y debería funcionar en versiones anteriores como ME, 95 y 98.

Este es mi propio código, y todos son libres de usarlo. http://pastebin.com/ccw3mWtw

Llame a la función ExitWindowsEx API en kernel32.dll

COMIDA

 $ bzr branch http://bzr.savannah.gnu.org/r/grub/trunk/grub $ vi grub/grub-core/commands/acpihalt.c +303 

o aquí en un espejo de Github:

https://github.com/dajhorn/grub/blob/trunk/grub/grub-core/commands/acpihalt.c#L303