mov $0x58, %al # 2 bytes: b0 58
mov $0xfee1dead, %ebx # 5 bytes: bb ad de e1 fe
mov $0x28121969, %ecx # 5 bytes: b9 69 19 12 28
mov $0x4321fedc, %edx # 5 bytes: ba dc fe 21 43
int $0x80 # 2 bytes: cd 80
Deve ser executado como root.
Isso equivale a pressionar o botão liga / desliga e não é uma maneira segura de desligar o PC. Certifique-se de fechar todos os aplicativos abertos e executar sync
para liberar todos os buffers do sistema de arquivos antes de executar este programa, para minimizar pelo menos o risco de corrupção de arquivos.
Execução de teste
$ as -o poweroff.o poweroff.s
$ ld -o poweroff poweroff.o
ld: warning: cannot find entry symbol _start; defaulting to 0000000000400078
$ sudo sh -c 'sync && ./poweroff'
root's password:
Seguido pela escuridão.
Como funciona
int $0x80
chama uma interrupção de software. Ele funciona em x86 e x64, mas está obsoleto há mais de uma década e não deve ser usado no código de produção. código x64 deve usar em seu syscall
lugar. O x86 deve ser usado sysenter
, mas é muito complicado para o código de golfe.
A ação resultante do syscall depende dos registros EAX - EDX, ESI e EDI. A Referência do Syscall do Linux mostra todos os syscalls disponíveis via int $0x80
.
Quando o EAX retém 0x58 (88) , a reinicialização é chamada, que também pode ser usada para desligar, adormecer ou hibernar o computador, além de alternar entre os kernels e desativar ou ativar a combinação de teclas Ctrl - Alt - Del .
No início do programa - e compilando com as
ou gcc -nostdlib
, podemos garantir que estamos realmente no início do programa - a maioria dos registros é definida como 0 . Isso inclui o EAX, para que possamos mov $0x58, %al
definir os 8 bits inferiores do EAX para 0x58 , configurando o EAX para 0x58 . Isso economiza dois bytes ao zerar manualmente o registro com xor %eax, %eax
e mais um ao lado, mov $0x58, %eax
que codifica 0x58 em 32 bits.
Os dois primeiros argumentos para reinicialização são números mágicos, presumivelmente para impedir reinicializações acidentais, e são lidos nos registros EBX e ECX. A menos que esses números sejam iguais a certas constantes, a reinicialização se recusa a executar qualquer ação.
O primeiro número mágico deve ser igual a 0xfee1dead ( sentir-se morto ), provavelmente se referindo ao desligamento / morte do PC.
O segundo número mágico pode ser igual a quatro constantes diferentes, embora os três últimos não funcionem nas versões antigas do Linux. Todos eles parecem se referir à alimentação subsequente / nascimento do PC.
0x28121969 representa o aniversário de Linus Torvalds (28 de dezembro de 1969).
0x05121996 representa o aniversário de Patricia Torvalds (5 de dezembro de 1996).
0x16041998 representa o aniversário de Daniela Torvalds (16 de abril de 1998).
0x20112000 representa o aniversário de Celeste Torvalds (20 de novembro de 2000).
Patricia, Daniela e Celeste Torvalds são as três filhas de Linus Torvalds.
O registro EDX seleciona o tipo de "reinicialização" que queremos. 0x4321fedc é RB_POWER_OFF , desligando o PC e desligando-o.
Finalmente, o valor do registro ESI é ignorado para RB_POWER_OFF ; o valor do registro EDI é totalmente ignorado pela reinicialização .
Versão alternativa, somente x64, 19 bytes
No x64, podemos usar um syscall apropriado para a mesma contagem de bytes.
mov $0xa9, %al # 2 bytes: b0 a9
mov $0xfee1dead, %edi # 5 bytes: bf ad de e1 fe
mov $0x28121969, %esi # 5 bytes: be 69 19 12 28
mov $0x4321fedc, %edx # 5 bytes: ba dc fe 21 43
syscall # 2 bytes: 0f 05
As únicas diferenças estão na instrução ( syscall
vs int $0x80
), no valor de __NR_REBOOT ( 0xa9 vs 0x58 ) e nos registros envolvidos.