Hone logo
Hone
Problems

Simple Assembly Code Generator

This challenge tasks you with building a basic assembly code generator in Go. The goal is to take a simplified instruction set and generate corresponding assembly code (specifically, x86-64 NASM syntax) for a given program represented as a list of instructions. This is a fundamental step in compilers and interpreters, allowing you to translate high-level code into machine-executable instructions.

Problem Description

You are to implement a function GenerateAssembly(instructions []Instruction) string. This function will receive a slice of Instruction structs, each representing a single instruction in your simplified instruction set. The function should return a string containing the generated assembly code in NASM syntax.

The Instruction struct is defined as follows:

type Instruction struct {
	OpCode    string // e.g., "mov", "add", "sub", "jmp"
	Operand1  string // e.g., "rax", "rbx", "10", "myVar"
	Operand2  string // e.g., "rbx", "20", "" (empty string if not needed)
	Comment   string // Optional comment for the generated assembly
}

The generated assembly code should be well-formatted and readable. Each instruction should be on a new line. Comments should be included as specified in the Comment field of the Instruction struct.

Key Requirements:

  • Correct Syntax: The generated assembly code must be valid NASM syntax for x86-64.
  • Instruction Mapping: The function must correctly translate the OpCode to the appropriate assembly instruction. For this challenge, you only need to support the following opcodes:
    • mov: Move data (e.g., mov rax, 10)
    • add: Add two operands (e.g., add rax, rbx)
    • sub: Subtract two operands (e.g., sub rax, rbx)
    • jmp: Jump to a label (e.g., jmp myLabel)
  • Operand Handling: The function must correctly handle the operands for each instruction. Assume that all operands are valid for the given opcode.
  • Comments: The function must include the comment provided in the Comment field, if present.

Examples

Example 1:

Input: []Instruction{
    {OpCode: "mov", Operand1: "rax", Operand2: "10", Comment: "Initialize rax"},
    {OpCode: "add", Operand1: "rax", Operand2: "rbx", Comment: "Add rbx to rax"},
}
Output:
; Initialize rax
mov rax, 10
; Add rbx to rax
add rax, rbx

Example 2:

Input: []Instruction{
    {OpCode: "jmp", Operand1: "myLabel"},
}
Output:
jmp myLabel

Example 3: (Edge Case - Empty Instructions)

Input: []Instruction{}
Output:
; (Empty program - no assembly generated)

Constraints

  • The input instructions slice can contain up to 100 instructions.
  • OpCode will always be one of: "mov", "add", "sub", or "jmp".
  • Operand1 and Operand2 will be strings containing valid register names (e.g., "rax", "rbx") or integer literals (e.g., "10", "20").
  • The generated assembly code should not include any unnecessary whitespace.
  • Performance is not a primary concern for this challenge. Focus on correctness and readability.

Notes

  • Consider using a switch statement to handle the different opcodes.
  • Remember to include a newline character (\n) at the end of each line of assembly code.
  • The generated assembly code is intended to be a simplified representation and does not need to handle complex features like function calls, local variables, or memory allocation.
  • The comment should be prefixed with a semicolon (;) to indicate it's a comment in NASM syntax.
  • For the jmp instruction, the operand is treated as a label. No label definition is required in the generated code.
  • The program should handle the case where the input slice is empty gracefully, by generating a comment indicating an empty program.
Loading editor...
go