【问题标题】:Segfault when storing reg to var in section .DATA在 .DATA 部分中将 reg 存储到 var 时出现段错误
【发布时间】:2021-07-28 05:55:31
【问题描述】:

所以我正在尝试使用 x86 编写一些代码,但我似乎无法让它将寄存器的内容移动到内存中的某个位置。

代码就是这样

global  main

SECTION .DATA
  var_i: DD  0

SECTION .TEXT
    main:
      push  DWORD 4
      pop   EAX
      mov   [var_i], EAX

    mov   EAX,  0
    ret

我在代码上使用 nasm 和 gcc。 我遇到的问题是,每当我尝试移动到内存中的位置时,它都会出现段错误

【问题讨论】:

  • 你为什么要pushpop来加载eax?试试这个:mov eax,4
  • 使用 push 和 pop 加载到 eax 是因为这是编译器的一部分,并且用于评估子表达式的字符串模板可能会以其评估值践踏注册表,这实际上只是int i = 4 的编译形式;如果我使用 move 将 4 加载到 EAX 中,仍然会发生段错误
  • 无论如何,您都会丢弃 REGISTER(而不是注册表)EAX。
  • 我明白这一点。问题是,如果你有类似int i = ( 5 + (7 * 8)); 的东西,它会变成^(= (VAR_DECL int i) ^(+ 5 ^(* 7 8))) 形式的 ast。正在构建的编译器不允许进行任何优化,因此当它作为字符串模板输出时,它会通过自下而上的 ast 表达式进行递归
  • 您的问题是问为什么会出现段错误,我正在尝试帮助您简化代码,以便您找到问题所在。您显示的代码是否真的崩溃了?

标签: assembly x86 segmentation-fault nasm sections


【解决方案1】:

您使用的是哪种系统/对象格式?我猜你在 Linux 或 Unix 上使用 ELF,因为这可以解释你的问题:

ELF 中的部分名称区分大小写,大多数基于 ELF 的操作系统的特殊部分 .text.data 可以理解,但您的部分 .TEXT.DATA 没有意义。结果,他们只是在其他部分之后卡在可执行文件中并获得相同的访问权限。如果您只是链接上面的代码,那将在.fini 部分之后,因此它将是可执行和只读的。因此,当您尝试写入变量时,会出现段错误。

更改您的代码以使用 .data.text 作为部分名称,它应该可以工作。

【讨论】:

  • 谢谢,这是问题所在。
猜你喜欢
  • 2021-12-22
  • 2021-01-22
  • 2016-11-04
  • 2014-05-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-02-24
相关资源
最近更新 更多