最近我一直在学习NASM x86组装。在编写代码时,每当我使用int 21h
或int 80h
或任何中断时,它都会返回分段错误。整个计划是:
section .data
msg: dw 'Hello World!', 10
section .text
global _main
_main:
mov eax, 4
mov ebx, 1
mov ecx, msg
int 80h
我可以获得有关NASM的更多信息的任何帮助或提示。非常感谢。
答案 0 :(得分:3)
每当我使用
时int 21h
或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
...它会返回分段错误。
在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个字节(=无)。
您必须在mov edx, 13
指令之前添加指令int 80h
。
分段错误发生在以后!
作为汇编语言的初学者,你应该首先实现什么汇编程序:每个汇编程序指令代表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将按照int 80h
指令解释RAM中的字节作为指令并执行它们......