views:

1518

answers:

5

How can I shutdown the computer using only assembly code?

+4  A: 

take a look here and here

evilpenguin
-1 your first link gives a 404, the second just a list on an assembly forum...
Abel
I'm sorry, but you realise I don't maintain those websites. At the time I posted the answer, the links were valid and relevant.
evilpenguin
+1  A: 

Call the ExitWindowsEx API function in kernel32.dll

Andrew Grant
Can you please provide code for loading a .dll in assembly. Thanks! :)
slacy
nope, but feel free to google for it!
Andrew Grant
+5  A: 

You need to say what processor family it is and which OS you're using. Also what privileges your code is running under - if it's kernel code then it has more privileges than user code.

Assuming you're using some member of the Windows NT family (including XP or Vista) on an Intel x86 family CPU, and your code is normal (userspace) code, then... you need to call the Windows built-in function to do this. You can't just execute some magic sequence of assembly.

Even if you could just execute some magic sequence of assembly, you wouldn't want to - you almost certainly want to give the OS chance to write data from the disk cache to disk, and do other graceful-shutdown stuff.

If you're writing your own OS for x86, then you need to look at the ACPI (or APM) specs. If GPL code is OK, then the relevent Linux kernel routines are here (ACPI) and here (APM).

user9876
Is there a PC BIOS command to power off the computer? I suppose so, and that might be good enough for this purpose. It won't be clean, but it'll get the job done.
slacy
I've added links to the Linux kernel code that shuts down the PC. The APM one just calls into the BIOS. It's a bit complex because Linux is 32-bit, and the BIOS is 16-bit, so it has to transition to a different CPU mode.
user9876
+3  A: 

In Linux read reboot(2).

sources files of interest:

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

not a complete answer but i think it's a good start. I'll have to read my BIOS machine code to see what they do. but this part is machine specific. maby if you know wich IC contol power on your motherboard you can figure out wich IO port, register and command you need. then setup proper board/devices states and then issue command to turn the power off.

BIOS manage power via INT 15h ah=53h ( so called Advanced Power Management aka APM ) function al=07 used in Linux is the set power state cmd. parameters bx=0001h mean all devices and cx=0003k mean stop.

jef
A: 

From 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);
 }
}
larz