我只是想打印“Hello!”在屏幕上,但我遇到了 SegmentationFault 错误。 我有两个程序,一个运行正常,另一个出现错误。
运行良好的代码:
global _start
section .text
_start:
mov rdi,1
mov rsi,hello_world
mov rdx,13
mov rax,1
syscall
; exit(result)
mov rax,60
mov rdi,0
syscall
hello_world: db "Hello World!",10
给出SegmentationFault的代码:
global _start
section .text
_start:
mov rdi,1
mov rsi,hello_world
mov rdx,13
mov rax,1
syscall
hello_world: db "Hello World!",10
; exit(result)
mov rax,60
mov rdi,0
syscall
第二个代码所需的输出应该是:Hello world!
有人可以解释一下为什么第一个代码工作正常而第二个代码出错。
正如 Michael 在评论中所说,问题就来自于此
hello_world: db "Hello World!",10
。
要理解为什么会发生这种情况,您首先必须知道程序在内存中是如何表示的。维基百科的对象文件页面可能是一个很好的开始,可以更详细地了解这一点。但简单来说,在这个例子中我们感兴趣的是 2 种段类型:数据段和代码段。
程序的代码段(或文本段)包含机器运行程序必须执行的指令。通常,当加载到主内存中时(当您执行程序时),此代码段将变为只读。这主要是出于安全原因,您可以在包含已初始化的静态变量。字符串“Hello World!”在你的程序中就是这样一个变量的一个很好的例子。因此,要编写“具有良好实践”的汇编示例,您应该利用这两个不同的段,可以在此处
找到 Hello World 示例。
现在,当执行程序时,CPU将加载程序计数器(PC)指向的操作,执行它,并递增PC以使其指向下一条指令。这是可行的,因为 CPU 知道指令的大小,因此可以正确地递增 PC。在您的代码中,这一切都很顺利,CPU 将正确执行,直到到达 hello_world: db "Hello World!",10