x64,为什么以下程序集会导致分段错误?

时间:2018-04-02 14:03:47

标签: assembly segmentation-fault 64-bit

我有以下汇编代码:

.data
.text

entry_point:
    pushq %rbp
    movq %rsp, %rbp
    popq %rbp
    ret

.global _main
_main:
    pushq %rbp
    movq %rsp, %rbp
    call entry_point
    popq %rbp
    ret

在我的MacBook上,它编译并运行正常,但我只是试图让它在Linux / Ubuntu 17.x上运行,它给我一个分段错误。我用GDB运行它,它只是告诉我有一个SIGSEGV? (),......没什么用处。

在与LLDB核对后,它告诉我:

... SIGSEGV: invalid address (fault address: 0x1)
memory read failed for 0x0

但是仍然不确定这意味着什么,我不知道为什么它会出现错误,因为程序对我来说是两个具有堆栈帧设置和简单调用的函数?

我的程序的入口点是_main程序。 libc与我的汇编程序相关联。

根据建议,我重新编写了汇编程序,使用系统退出调用而不是“ret”:

.data
.text
entry_point:
    pushq %rbp
    movq %rsp, %rbp
    popq %rbp
    ret

.global main
main:
    pushq %rbp
    movq %rsp, %rbp
    call entry_point
    popq %rbp
    movq $60, %rax
    movq $2, %rdi
    syscall

我将此程序运行为:

as foo.s -o foo.o
ld foo.o -lc
./a.out

但我得到以下内容:

ld: warning: cannot find entry symbol _start; defaulting to 00000000004001d3

1 个答案:

答案 0 :(得分:0)

  

GET /explore?coord=lat,lng GET /explore?ne=lat,lng&sw=lat,lng

该命令不会构建有效的可执行文件。特别是,libc需要某些初始化(通常由ld foo.o -lc执行,由编译器驱动程序添加),并且此处不会发生初始化。

通常,您应该从不直接将用户级程序与crt0.o链接 - 使用编译器驱动程序,例如ld

gcc

将正确构建您的程序。