为什么下面的代码没有出现分段错误?
global _start
section .data
_start:
mov ecx, 3
xor byte[_start+1], 0x02
mov eax, 1
mov ebx, 2
int 80h
我预计它会在.text
部分运行相同代码时在同一位置(标有注释的行)进行段错误:
global _start
section .text ; changed from data to text
_start:
mov ecx, 3
xor byte[_start+1], 0x02 ; ******get segmentation fault here
mov eax, 1
mov ebx, 2
int 80h
现在,我知道.data
部分用于读写,部分.text
仅供读取使用。
但是,当我尝试访问非法内存地址时,为什么会这么重要?
对于此处的示例,我预计在.data
部分也会出现细分错误,与我在第.text
部分中获得的位置相同。
答案 0 :(得分:3)
[_start+1]
显然不是非法地址。它是5字节编码mov ecx, 3
的一部分。 (查看objdump -Mintel -drw a.out
以查看使用十六进制机器代码进行反汇编。)
IDK为什么您认为写入.data
中已定义内容的地址会出现问题。使用像db
之类的伪指令将字节汇编到数据部分更为常见,但汇编程序会很乐意将指令或db
汇编到字节中的任何位置。
来自.data
版本的期望的崩溃来自_start
没有执行权限的映射,但Linux没有严格的默认值来应用no-exec
_start
中.data
的版本恰好可行,因为您在使用读取,写入和执行权限映射该页面的内核上运行它。
尝试写入.text
部分当然是segfaults的版本,因为它映射为只读。