Search code examples
assemblycompiler-constructionx86gnu-assembler

Variable assignment in GAS assembly


I am working through Jack Crenshaw's "Let's Build A Compiler." I am translating his Motorola 680x0 instructions into x86 GAS syntax.

During variable assignment, the desired semantics are to create a reference to a variable by using PC-relative addressing (at least that's what Crenshaw is going for). The variable can be accessed in Motorola syntax by:

MOVE x(PC), D0

where x is the variable name.

Here is what the actual procedure looks like for an assignment (in Pascal):

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

Trying to mimic the same syntax in GAS assembly results in a junk expression error. Hopefully this question isn't too naive, but I've been searching for several days now and don't see an obvious solution.

How do I accomplish this with GAS syntax for an x86 processor on Linux (i386)? I'm looking for the simplest means to accomplish variable assignment. I'm using as and ld for my assembler and compiler, respectively.

Here's a link to where I am currently, chapter 3 in Crenshaw:

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


Solution

  • x86-32 doesn't have PC-relative addressing, but x86-64 does. In any case, on x86 you don't need to go through a register, you can use a symbol directly in the MOV. As such, the simplest way to write that would be: MOV source_register, variable_name. If you do want to mimic the original code more closely, you can use LEA like this:

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