linux - 在我的代码末尾进行系统调用后出现程序集段错误

标签 linux assembly x86 nasm system-calls

我正在试验并有以下汇编代码,它运行良好,除了我在程序结束前收到“段错误(核心已转储)”消息:

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。

最佳答案

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

作为 n.m.在评论中说,问题是你没有退出程序,所以执行运行到垃圾代码并且你得到一个段错误。

你需要的是:

;; 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

关于linux - 在我的代码末尾进行系统调用后出现程序集段错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38173575/

相关文章:

linux - 循环/输入逻辑流程问题(NASM x86 程序集)

linux - 通过命令行添加启动(Ubuntu)

linux - 将长标准输出管道传输到 tee 命令有时会导致截断

c - 打印文件传输额外的行

c# - 对浮点变量求反的不同方法会生成不同的程序集

c++ - 汇编操作的时间

syntax - AT&T 语法如何处理其他助记符和操作数大小后缀之间的歧义?

linux - 从 ELF 中删除汇编指令

php - 这是创建 ajax 上传表单的安全方法吗?

c++ - linux下计算周期数