分段错误:int 80h

Segmentation Fault: int 80h

最近在学习NASM x86 汇编。在编写我的代码时,每当我使用 int 21hint 80h 或与此相关的任何中断时,它 returns 都是一个分段错误。整个程序是:

section .data
    msg: dw 'Hello World!', 10
section .text
    global _main

_main:
    mov eax, 4
    mov ebx, 1
    mov ecx, msg
    int 80h

非常感谢任何关于我在哪里可以了解更多 NASM 的帮助或提示。

whenever I use int 21h or int 80h

int 指令是 call 指令的特殊变体,它在 操作系统.

中调用某些函数

这当然意味着 int 指令在不同操作系统中的行为不同:

int 21h

中断 21h 用于 MS-DOS 和 16 位 Windows (Windows 3.x)。因此,该指令只能用于 MS-DOS 和 16 位 Windows 程序。

32 位(或 64 位)Windows 程序不支持中断。 Linux也不支持这个中断

int 80h

32 位 Linux 程序支持此中断。 64 位 Linux 版本可以 运行 32 位 Linux 程序(但你必须确保你创建的程序确实是 32 位程序而不是 64-位程序)。

其他中断(如int 10h

... Linux 和最近的 Windows 版本都不支持。 (它们在 16 位 Windows 中受支持。)

int 80h ... it returns a segmentation fault.

在 Linux 下,您可以 运行 strace 命令查看 int 80h 系统调用发生了什么。

我用你的程序做了这个并得到了以下输出:

$ strace ./x.x
execve("./x.x", ["./x.x"], [/* 54 vars */]) = 0
strace: [ Process PID=3789 runs in 32 bit mode. ]
write(1, "", 0)                         = 0
--- SIGSEGV {si_signo=SIGSEGV, si_code=SI_KERNEL, si_addr=NULL} ---

可以看到int 80h没有产生错误但是执行正确

但是 edx 寄存器的值为 0。因此 int 80h 将输出您的 "Hello World".

的前 0 个字节(= 无)

您必须在 int 80h 指令之前添加指令 mov edx, 13

分段错误稍后发生!

作为汇编语言的初学者,您首先应该了解什么是汇编程序:每个汇编程序指令代表RAM内存中的一些字节。

例如指令mov eax, 4表示字节184, 4, 0, 0, 0或指令int 80h表示字节205, 128.

您的汇编程序在指令 int 80h 之后结束。然而,RAM 内存当然不会在字节 205, 128 之后结束。 RAM 内存将包含 随机 字节后的数据 205, 128.

可能在 RAM 中找到的字节之后的字节是 160, 0, 0, 0, 0,等于 mov al, [0] 会导致分段错误。

您必须在 int 80h 指令之后添加一些指令来停止您的程序。否则 CPU 会将 RAM 中 int 80h 指令之后的字节解释为指令并执行它们...