HASM

Hendrik's Assembly Language
A Custom Assembly Language & Compiler

Project Overview

HASM (Hendrik's Assembly Language) is a custom x86-64 assembler written entirely in C, located in the HASM/ directory of this project. It compiles modern, readable assembly code directly into native ELF64 executables for Linux. HASM features a clean syntax, robust error reporting, and a simple, transparent implementation, demonstrating low-level programming and system architecture skills.

Direct ELF64 output: The assembler generates native ELF64 executables for Linux from x86-64 assembly source code.
Low-level mastery: Manual instruction encoding, ELF header construction, and direct binary output, all implemented in C for maximum transparency and control.

HASM was primarily created as a personal educational project to deepen my understanding of low-level programming, assembler design, and the ELF binary format. The codebase is clean and well-commented, so it may also be useful or approachable for others interested in systems programming.

The assembler is thoroughly tested with a comprehensive suite of test cases covering all supported instructions and edge cases, ensuring reliability and correctness.

For testing and verification, I used the Defuse Online x86/x64 Assembler and Disassembler extensively. All test comparisons were written with the help of this tool to ensure that the output of HASM matched the expected machine code and behavior.

Note: HASM does not include a macro system, optimization passes, or a linker. It is focused on correctness, clarity, and educational value.

Key Features

Custom Assembly Syntax

Simplified, modern syntax designed for readability while maintaining full control over hardware resources and memory management.

Assembler Pipeline

Multi-phase assembler with tokenization, parsing, label resolution, and binary code generation.

ELF64 Binary Generation

Produces standard ELF64 (Executable and Linkable Format) binaries compatible with Linux systems.

x86-64 Support

Supports a wide range of x86-64 instructions, registers, and addressing modes.

Error Reporting

Detailed error messages with line and column information for easier debugging and learning.

Technical Deep Dive

Language Design

  • Simplified syntax inspired by x86 assembly but with improved readability.
  • Support for labels and standard assembler directives (SECTION, GLOBAL, etc.).
  • Operand validation and addressing mode checks.

Assembler Architecture

  • Tokenization: Lexical analysis of source code into tokens.
  • Parsing: Construction of instruction and data structures from tokens.
  • Label Resolution: Resolves jump and call targets.
  • Code Generation: Encodes instructions and writes ELF64 binary output.

ELF Format Handling

  • Manual construction of ELF file headers and section tables.
  • Support for .text, .data, and .bss sections.
  • Direct binary output for Linux x86-64.

Instruction Encoding

  • Manual x86-64 instruction encoding and decoding.
  • Support for various addressing modes and operand types.

Error Handling

  • Detailed error messages with source location information.
  • Operand and instruction validation for robust assembly.

Project Significance & Learning Outcomes

What I Learned

Technical Challenges Overcome

Real-World Applications

Demo & Showcase

Hello World Example

GLOBAL _start

SECTION .data

    msg DB "Hello, World!" 0x0A

SECTION .text

_start:
    CALL HelloWorld
    JMP end
HelloWorld:
    MOV EDX 0x0E
    MOV ECX msg
    MOV EBX 0x01
    MOV EAX 0x04
    INT 0x80
    RET
end:
    MOV EBX 0x00
    MOV EAX 0x01
    INT 0x80

Download Executable

File: HelloWorld (ELF binary)

Platform: Linux x86-64

Size: 179 bytes

Disclaimer: This is a compiled ELF executable. Run at your own risk. The source code and assembler are located in the HASM/ folder.
Download HelloWorld
0
Lines of C Code (including headers)
0
Supported Instructions
0
Compiler Passes
0
Test Case Lines

How to Build & Run

  1. Ensure you have a C compiler (GCC) and Make installed on your Linux system.
  2. Navigate to the HASM/ directory in your terminal.
  3. Run the following command to build the assembler:
make
  1. To assemble a program, run:
./HASM input.hasm -o output
chmod +x output
./output