代码在从.data节运行时有效,但在.text

时间:2016-07-01 19:01:16

标签: assembly x86 segmentation-fault

为什么下面的代码没有出现分段错误?

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部分中获得的位置相同。

1 个答案:

答案 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的版本,因为它映射为只读。