【问题标题】:Variable assignment in GAS assemblyGAS 装配中的变量赋值
【发布时间】:2014-09-05 13:19:12
【问题描述】:

我正在研究 Jack Crenshaw 的“让我们构建一个编译器”。我正在将他的 Motorola 680x0 指令翻译成 x86 GAS 语法。

在变量赋值期间,所需的语义是通过使用 PC 相对寻址来创建对变量的引用(至少 Crenshaw 是这样做的)。可以通过以下方式在 Motorola 语法中访问该变量:

移动 x(PC), D0

其中 x 是变量名。

这是赋值的实际过程(在 Pascal 中):

procedure Assignment;
var Name: char;
begin
   Name := GetName;
   Match('=');
   Expression;
   EmitLn('LEA ' + Name + '(PC),A0');
   EmitLn('MOVE D0,(A0)')
end;

试图在 GAS 汇编中模仿相同的语法会导致垃圾表达式错误。希望这个问题不会太天真,但我已经搜索了几天,没有看到明显的解决方案。

如何在 Linux (i386) 上使用 GAS 语法为 x86 处理器完成此任务?我正在寻找完成变量赋值的最简单方法。我的汇编器和编译器分别使用asld

这是我目前所在位置的链接,Crenshaw 的第 3 章:

http://compilers.iecc.com/crenshaw/tutor3.txt

【问题讨论】:

  • 你需要它来使用PC相对寻址吗?如果没有,似乎'movl %eax,' + Name 会做(没有读过 Crenshaw 的书)。

标签: assembly compiler-construction x86 gnu-assembler


【解决方案1】:

x86-32 没有 PC 相对寻址,但 x86-64 有。 无论如何,在 x86 上你不需要通过寄存器,你可以直接在MOV 中使用符号。因此,最简单的写法是:MOV source_register, variable_name。 如果您确实想更接近地模仿原始代码,可以像这样使用LEA

LEA variable-name, temp_register
MOV source_register, (temp_register)

【讨论】:

  • 我认为这种方法需要先声明变量。克伦肖似乎没有宣布任何事情。抱歉,我忘了在原来的问题中提到这一点。
  • 它不必被声明为首先,但它确实需要最终在某个地方定义,并带有存储分配。
  • 实际上,这很有帮助,声明可以是内联的,还是需要在 .data 或 .bss 部分中?
  • 它可以内联在.text,但代码部分通常是只读的。使用.lcomm 指令分配变量很容易,它会自动将其放入.bss。否则你可以使用.previous.pushsection/.popsection
猜你喜欢
  • 2016-09-21
  • 2020-02-21
  • 2017-04-21
  • 2015-02-27
  • 1970-01-01
  • 1970-01-01
  • 2015-05-18
相关资源
最近更新 更多