使用程序集应用程序关闭Linux时出现分段错误

时间:2011-07-03 19:23:03

标签: linux assembly segmentation-fault gnu shutdown

以下应用程序在执行时会生成分段错误

.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

修改

即使只是调用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 个答案:

答案 0 :(得分:5)

警告:在致电sync(2)之前,请记得reboot(2)

reboot(2)系统调用需要4个参数。您将它与libc混淆 包装

警告:在致电sync(2)之前,请记得reboot(2)

(它实际上需要 magic * 参数,以便人们必须重新阅读文档,不要忘记调用sync(2)。)

警告:在致电sync(2)之前,我是否说过reboot(2)

答案 1 :(得分:2)

我正在添加 final&工作源代码,因为这个问题可能会引起某些人的兴趣:

                                     # 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()

答案 2 :(得分:1)

来自linux/i386/syscall.S:函数编号应放在%eax中,以下寄存器中的任何参数依次为:%ebx,%ecx,%edx,%esi,%edi和%ebp。

这就是为什么代码中的最后一个movl %eax,0应该更改为movl %ebx, 0