A lightweight C compiler targeting real-mode/DOS systems, designed for simplicity, educational purposes, and retro computing. NCC compiles C code to x86 assembly and can generate bootloaders, MS-DOS executables, and bare-metal programs for 16-bit systems.
- Full C Compiler Pipeline: Lexical analysis, parsing, type checking, and code generation
- Multiple Target Formats:
- MS-DOS executables (.COM files)
- Bootloader binaries (512-byte MBR compatible)
- Custom origin addresses for bare-metal programming
- Advanced Language Support:
- Structs with nested field access
- Arrays and array initialization
- Control flow (if/else, while, do-while, for loops)
- Function calls and parameters
- Inline assembly with
__asm() - Preprocessor with includes and macros
- Unary and compound expressions
- Development Features:
- AST debugging and visualization
- Line number tracking through preprocessing
- Built-in assembler (NAS - Nathan's Assembler)
- Optimization passes
- Comprehensive error reporting
makeFor a clean build:
make clean && make# Compile to assembly
./bin/ncc source.c -o output.asm
# Compile MS-DOS .COM executable
./bin/ncc -com program.c -o program.com
# Compile bootloader
./bin/ncc -sys bootloader.c -o boot.bin
# Custom origin address
./bin/ncc -disp 0x8000 kernel.c -o kernel.bin| Option | Description |
|---|---|
-o <file> |
Output filename (default: output.asm) |
-com |
Target MS-DOS executable (ORG 0x100) |
-sys |
Target bootloader (ORG 0x7C00) |
-disp <addr> |
Set custom origin displacement address |
-I<path> |
Add include search path |
-O<level> |
Optimization level (0=none, 1=basic) |
-S |
Stop after assembly generation (don't assemble) |
-d |
Debug mode (print AST) |
-dl |
Debug line tracking |
-h |
Display help |
void main() {
printstring("Hello, World!$");
}
void printstring(char* str) {
__asm("mov dx, [bp+4]"); // Get string parameter
__asm("mov ah, 0x09"); // DOS print string function
__asm("int 0x21"); // Call DOS interrupt
}Compile with:
./bin/ncc -com hello.c -o hello.comvoid main() {
// Clear screen and print message
__asm("mov ah, 0x06"); // Scroll up function
__asm("mov al, 0"); // Clear entire screen
__asm("mov bh, 0x07"); // Attribute
__asm("mov cx, 0"); // Upper left
__asm("mov dx, 0x184F"); // Lower right
__asm("int 0x10"); // BIOS video interrupt
// Print boot message
// ... (additional boot code)
// Infinite loop
while(1) {}
}Compile with:
./bin/ncc -sys boot.c -o boot.bin# Test MS-DOS program
make test_com
# Test bootloader in QEMU
make test_os# Compile and run in QEMU
./bin/ncc -sys bootloader.c -o boot.bin
qemu-system-x86_64 -fda boot.binNCC is structured as a traditional compiler with these phases:
- Preprocessor (
preprocessor.c) - Handle includes and macros - Lexer (
lexer.c) - Tokenize source code - Parser (
parser.c) - Build abstract syntax tree - Type Checker (
type_checker.c) - Semantic analysis - Code Generator (
codegen.c) - Emit x86 assembly - Assembler (NAS) - Convert assembly to machine code
- AST Management - Full abstract syntax tree with cleanup
- Struct Support - Complete struct parsing and code generation
- Loop Constructs - While, do-while, and for loop implementations
- Expression Handling - Unary operations and compound expressions
- Memory Management - String literals and array operations
- Error Handling - Comprehensive error reporting system
int,char,void- Pointers and pointer arithmetic
- Arrays (single and multi-dimensional)
- Structs with nested access
if/elsestatementswhileloopsdo-whileloopsforloops- Function calls
- Arithmetic:
+,-,*,/,% - Comparison:
==,!=,<,>,<=,>= - Logical:
&&,||,! - Assignment:
=,+=,-=, etc. - Unary:
++,--,&,*
- Inline assembly with
__asm() - Preprocessor directives (
#include,#define) - Function parameters and local variables
- Global variables and initialization
- String literals and character constants
See CONTRIBUTING.md for detailed contribution guidelines.
NCC is designed for educational and retro computing purposes. NCC is licensed under the MIT license. See here: https://opensource.org/license/mit
- GCC or compatible C compiler (for building NCC)
- Make build system
- QEMU (optional, for testing bootloaders)
- Linux/Unix environment or Windows with MSYS2/WSL
- Check the test files in
test/for usage examples - Use
-dflag to debug AST generation - Use
-dlflag to trace preprocessor line mappings - Examine generated assembly with
-Sflag