Ошибка сегментации при завершении работы Linux с приложением сборки - PullRequest
2 голосов
/ 03 июля 2011

Следующее приложение генерирует Ошибка сегментации при выполнении:

.set __NR_reboot, 169
.set LINUX_REBOOT_CMD_POWER_OFF, 0x4321FEDC

.section .text
.globl _start
_start:
   movl $LINUX_REBOOT_CMD_POWER_OFF, %ebx
   movl $__NR_reboot, %eax
   int $0x80

Это довольно простое приложение, и я, должно быть, упускаю что-то действительно очевидное. Кто-нибудь может мне помочь?

Он был скомпилирован с:

as shutdown.s -o shutdown.o
ld shutdown.o -o shutdown

EDIT:

Даже простое приложение, которое просто вызывает syscall sync (), генерирует Ошибка сегментации :

.set __NR_sync, 36

.section .text
.globl _start
_start:
   movl $__NR_sync, %eax
   int $0x80

   movl $1, %eax         #syscall exit
   movl $0, %eax
   int $0x80

Ответы [ 3 ]

5 голосов
/ 03 июля 2011

ПРЕДУПРЕЖДЕНИЕ : не забудьте sync(2) перед вызовом reboot(2).

Системный вызов reboot(2) принимает 4 параметра. Вы путаете его сОболочка libc.

ПРЕДУПРЕЖДЕНИЕ : не забудьте sync(2) перед вызовом reboot(2).

(на самом деле он принимает параметры magic *, так чтолюди должны перечитать документацию и не забыть позвонить sync(2).)

ПРЕДУПРЕЖДЕНИЕ : я говорил, что вам нужно sync(2) перед вызовом reboot(2)?

2 голосов
/ 04 июля 2011

Я добавляю окончательный и рабочий исходный код , так как этот вопрос может заинтересовать кого-то в будущем:

                                     # For the right sys_call numbers on your arch,
                                     # check <asm/unistd_32.h> (or unistd_64.h)

.set __NR_sync, 36                   # sys_call sync()    
.set __NR_reboot, 88                 # sys_call reboot()

.set LINUX_REBOOT_MAGIC1, 0xfee1dead # flags are specified in: <linux/reboot.h>
.set LINUX_REBOOT_MAGIC2, 672274793
.set LINUX_REBOOT_CMD_POWER_OFF, 0x4321fedc
.set LINUX_REBOOT_CMD_RESTART, 0x01234567

.section .text
.globl _start
_start:
   movl $__NR_sync, %eax             # call sync()
   int $0x80

   movl $__NR_reboot, %eax
   movl $LINUX_REBOOT_MAGIC1, %ebx
   movl $LINUX_REBOOT_MAGIC2, %ecx
   movl $LINUX_REBOOT_CMD_RESTART, %edx
   #movl $0, %esi
   int $0x80                         # call reboot()

   movl $1, %eax
   movl $0, %ebx
   int $0x80                         # call exit()
1 голос
/ 04 июля 2011

С linux / i386 / syscall.S : номер функции должен быть помещен в% eax и любые аргументы в следующих регистрах по порядку:% ebx,% ecx,% edx,% esi,% edi и% ebp.

Именно поэтому последние movl %eax,0 в коде должны быть изменены на movl %ebx, 0.

...