分段错误:int 80h
Segmentation Fault: int 80h
最近在学习NASM x86 汇编。在编写我的代码时,每当我使用 int 21h
或 int 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
指令之后的字节解释为指令并执行它们...
最近在学习NASM x86 汇编。在编写我的代码时,每当我使用 int 21h
或 int 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
orint 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".
您必须在 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
指令之后的字节解释为指令并执行它们...