3
\$\begingroup\$

Provided that I have written a simple microprocessor design in VHDL where I have decided what instructions it has to do each task, I will then have to write test code in machine language which is tedious and error prone.

A simple assembler would be like a “lite text processor” where it can convert assembly instructions to machine code by parsing text of the assembly language program. Each assembly instruction is a mnemonic and the parser will also figure our how to fit the parameters into the generated machine instruction word e.g register name, variable name e.t.c

Is there an easy solution to developer an assembler of such a nature?

\$\endgroup\$
1
  • \$\begingroup\$ Making a simple assembler for a RISC CPU is not very complex task, it can start with a Python script (I even made a crude Sparc assembler in VHDL for test benches). To the opposite, if you want to integrate a compilation environment (GCC, LLVM) you will have to add your architecture, there are porting guides, but it is a far more ambitious endeavour. \$\endgroup\$
    – Grabul
    Commented Jan 27, 2017 at 0:55

3 Answers 3

3
\$\begingroup\$

Puh, writing an assembler would actually imply writing a parser, and then writing some kind of Abstract syntax Tree-to-instructions converter.

I think this would, if you want to do it most simple, be done by defining a grammar (ie a set of instructions and registers and immediate value formats and how to combine them) and then generating a parser for that. You can go the Bison/Yacc/flex way about that, but I hear good things about ANTLR, so I'd give that a try.

In the medium run, you'd probably want to implement a clang or GCC backend. That would have the "nice" side effect that you could then compile e.g. C to your instruction set.

\$\endgroup\$
2
\$\begingroup\$

There is such a thing as a generic microcode assembler; mcasm is just one example that I found in a quick search.

As it happens, I just wrote a new processor myself last year, but I'm using a home-grown micro-assembler that a colleague wrote in Ruby, which I substantially rewrote. It's very simple; it basically allows you to define symbols representing bit fields whose values contain specific numbers of bits, and string those fields together to create complete instruction words. It also allows you to label instructions and use those labels as arguments to jump/call instructions, etc.

So the syntax ends up looking like this:

loop1:
    add, reg1, reg2;  // this is a comment
    jump, nc, loop1;
\$\endgroup\$
1
\$\begingroup\$

If your instruction set is small and simple, an assembler could be as simple as a bunch of switch/case statements. If your instructions all use the same bits for operands, you could separate their handling out from the main instruction handler. A simple algorithm in C would look like:

  1. Read a line of text.
  2. Call strtok() to break the line into tokens.
  3. Interpret the first token as an instruction. Use a bunch of if/else statements with strcmp() to find the opcode, then store it in the output word.
  4. Interpret the other tokens as operands. OR with the appropriate bits in the output word.
  5. If steps 3 or 4 failed, terminate with a helpful error message. Otherwise, write the complete output word to the output file.
  6. Repeat.

It would be even easier in a high-level language like Python. More complex features could include:

  • Named labels for branch instructions
  • Constant values
  • Memory addresses for code and data

If you want to do anything complicated, the suggestions in Marcus's answer are helpful. But if you just want to test your project, I'd keep it simple.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.