空ASM程序获得了信号

时间:2016-11-13 15:57:36

标签: assembly nasm

我正在学习集会,而我正在尝试运行一个非常简单的程序。

section .text
    global start
    global _main

start:
    call _main
    ret

_main:
    push 42
    ret

我在OSX 64位上使用NASM。这是我试过的:

$ nasm -f macho64 simple.asm -o simple.o
$ ld simple.o -o a.out
$ ./a.out
dyld: no writable segment
[1]    38021 trace trap  ./a.out
$
$ ld -lc -ldylib1.o -e start simple.o -o a.out
$ ./a.out
[1]    38134 segmentation fault  ./a.out
$
$ ld -macosx_version_min 10.8 -lSystem simple.o -o a.out
[1]    38134 segmentation fault  ./a.out
$

关注this post后,我在代码中添加了section .data

$ nasm -f macho64 simple.asm && ld simple.o && ./a.out
[1]    39119 killed     ./a.out

1)如何让我的程序不被杀?

2)为什么我的程序会获得这些信号( SIGTRAP SIGSEGV SIGKILL )?

3)我可以在哪里找到答案而不问?到目前为止,我发现的解释确实需要先前有关装配的知识。

修改

我理解push 42的错误,谢谢。我的程序在加载ld -macosx_version_min 10.8 -lSystem simple.o时运行。但是:

  • 加载ld simple.o

  • 后,我仍然有SIGTRAP
  • 加载ld -lc -ldylib1.o -e start simple.o

  • 后,我仍然遇到了段错误
  • 当我添加section .data并加载ld simple.o

  • 时,我仍然有一个SIGKILL
  • 我添加section .data并加载ld -macosx_version_min 10.8 -lSystem simple.o时出现总线错误

我想知道为什么我会得到那些信号(为了理解它是如何工作的)。我也想知道为什么我必须指定macosx_version_min以及如何在没有朋友告诉我的情况下找到它。

2 个答案:

答案 0 :(得分:2)

  

1)如何让我的程序不被杀?

不是C:你没有ret那样。您的代码不会从预先建立的环境中调用;您应该ret求什么?通过发出这样的指令,您的jmp - 当前位于%rsp的堆栈上的任何值,并进入可能位于进程外的地区空间,因此是SIGSEGV。

您必须明确告诉操作系统您的进程已通过系统调用终止其执行。

此外,ELF的起点通常是_start,而不是start,否则您应该向链接器指示。

  

当加载ld -lc -ldylib1.o -e start simple.o时,我仍然有段错误。

不要与C链接,除非您符合其执行模式。另外,我不明白你的意思是“用ld file.o加载”。

答案 1 :(得分:2)

您的主要问题很简单。在你的短程序中,你会在RET弹出它之前立即在堆栈上推送值42以跳转到它 - 这会导致segfault,因为它会跳转到地址00000042(32 -bit-mode),(在保护模式下)最有可能导致异常。