1

我正在试验并且有以下汇编代码,它工作得很好,除了我在程序结束之前收到“分段错误(核心转储)”消息:

GLOBAL _start

%define ___STDIN 0
%define ___STDOUT 1
%define ___SYSCALL_WRITE 0x04

segment .data
segment .rodata
    L1 db "hello World", 10, 0
segment .bss
segment .text
_start:
    mov eax, ___SYSCALL_WRITE
    mov ebx, ___STDOUT
    mov ecx, L1
    mov edx, 13
    int 0x80

最后有没有没关系ret;我仍然收到消息。

有什么问题?

我正在使用 x86 和 nasm。

4

1 回答 1

5

你不能ret从头开始;它不是一个函数,堆栈上没有返回地址。堆栈指针指向argc进程入口。

正如 nm 在评论中所说,问题在于您没有退出程序,因此执行运行到垃圾代码中并且您会遇到段错误。

你需要的是:

;; Linux 32-bit x86
%define ___SYSCALL_EXIT 1

// ... at the end of _start:
    mov eax, ___SYSCALL_EXIT
    mov ebx, 0
    int 0x80

(以上是 32 位代码。在您想要的 64 位代码中mov eax, 231(exit_group) / syscall,在 EDI 中具有退出状态。例如:

;; Linux x86-64
    xor   edi, edi     ;  or mov edi, eax    if you have a ret val in EAX
    mov   eax, 231     ; __NR_exit_group
    syscall
于 2015-06-01T19:05:52.297 回答