
Notepad is a bare-metal implementation of a text editor for the Microsoft Windows operating system, written entirely in Macro Assembler (MASM). Unlike standard software development involving high-level abstractions (C#, C++, Python), this project interacts directly with the Win32 API and the CPU registers, bypassing the C Runtime (CRT) entirely.
This repository serves as a reference implementation for systems programmers, malware analysts, and computer science students studying the PE (Portable Executable) format, Windows message loops, and low-level memory management. It demonstrates the dichotomy between legacy x86 (Flat Memory Model) and modern x64 (Microsoft x64 ABI) calling conventions within a single codebase.
Pre-built binaries: notepad.zip
Contains both x86 and x64 executables ready to run on Windows.
| Component | Specification | Notes |
|---|---|---|
| Assembler | ml.exe (x86) / ml64.exe (x64) | Microsoft Macro Assembler |
| Linker | link.exe | Microsoft Incremental Linker |
| Subsystem | WINDOWS | Graphical User Interface (GUI) |
| Entry Point | start | Custom entry, no main() wrapper |
| Resource Compiler | rc.exe | Compiles menus, icons, and manifests |
The application relies strictly on standard dynamic link libraries found in all Windows versions since XP:
The application implements a standard Windows Event-Driven Architecture. It does not poll for input; rather, it yields CPU time until the Operating System pushes a message to the thread's message queue.
The entry point initializes the WNDCLASSEX structure and spawns the main window. It then enters an infinite loop, consuming approximately 0% CPU when idle.
; Pseudo-assembly representation of the core loop (x64)
MessageLoop:
mov rcx, OFFSET msg
xor rdx, rdx
xor r8, r8
xor r9, r9
call GetMessage ; Blocking call, waits for OS event
test eax, eax
jz ExitProgram ; WM_QUIT received
; Modeless Dialog Handling (Find/Replace)
mov rcx, hFindReplaceDlg
mov rdx, OFFSET msg
call IsDialogMessage ; Checks if msg belongs to Find/Replace dialog
test eax, eax
jnz MessageLoop ; If handled, skip Dispatch
call TranslateMessage ; Virtual-Key -> character
call DispatchMessage ; Route to WndProc
jmp MessageLoop
The codebase highlights critical differences in assembly programming between 32-bit and 64-bit modes.
ret n).invoke macro for simplified API calls.Since malloc and free (C-Runtime) are unavailable, the application interfaces directly with the Windows Heap Manager via kernel32:
HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size)HeapFree(hHeap, 0, pMemory)This is critically used for:
The application uses Unicode (UTF-16 LE) throughout:
CreateWindowExW, SendMessageW, etc.MultiByteToWideCharInstead of using a basic EDIT control, the application uses RichEdit 2.0 (riched20.dll) which provides:
EM_FINDTEXTEXStyles: WS_CHILD | WS_VISIBLE | WS_VSCROLL | ES_MULTILINE | ES_AUTOVSCROLL | ES_NOHIDESEL
For word wrap toggle, horizontal scrolling is added/removed: WS_HSCROLL | ES_AUTOHSCROLL
File operations adhere to strict transactional steps to ensure data integrity:
GENERIC_READ or GENERIC_WRITEHeapAllocMultiByteToWideChar if neededThe search feature uses the Common Dialog Box Library (FindText / ReplaceText) for the UI, with search logic implemented via RichEdit messages:
EM_FINDTEXTEX with FINDTEXTEX structureEM_EXSETSEL to highlight matching textEM_REPLACESEL for text substitutionReal-time display of:
Ln X, Col Y| Shortcut | Action |
|---|---|
| Ctrl+N | New document |
| Ctrl+O | Open file |
| Ctrl+S | Save file |
| Ctrl+Shift+S | Save As |
| Ctrl+P | |
| Ctrl+Z | Undo |
| Ctrl+X | Cut |
| Ctrl+C | Copy |
| Ctrl+V | Paste |
| Ctrl+A | Select All |
| Ctrl+F | Find |
| Ctrl+H | Replace |
| F3 | Find Next |
| Shift+F3 | Find Previous |
| Del | Delete selection |
| Metric | Notepad ASM (x64) | Notepad ASM (x86) | MS Notepad (Win11) | VS Code |
|---|---|---|---|---|
| Disk Usage | ~20 KB | ~18 KB | ~200 KB + Deps | ~300 MB |
| RAM Usage (Idle) | ~1.5 MB | ~1.2 MB | ~12 MB | ~400 MB |
| Startup Time | < 10ms | < 10ms | ~200ms | ~2500ms |
| Dependencies | System DLLs only | System DLLs only | UWP / CRT | Electron / Node.js |
Note: The tiny memory footprint is due to the lack of garbage collection, JIT compilation, or interpreted runtime environments. The application maps directly to OS pages.
The project includes a PowerShell build script (build.ps1) that automates the assembly and linking process.
Clone the repository:
git clone https://github.com/wesmar/notepad.git
cd notepad
Run the Build Script:
.\build.ps1
The script will:
bin/ folderManual Compilation (x64 Example):
cd x64
rc /c65001 notepad.rc
ml64 /c /Cp /Cx /Zd /Zf /Zi main.asm
ml64 /c /Cp /Cx /Zd /Zf /Zi file.asm
ml64 /c /Cp /Cx /Zd /Zf /Zi edit.asm
link main.obj file.obj edit.obj notepad.res /subsystem:windows /entry:start /out:Notepad_x64.exe /MANIFEST:EMBED /MANIFESTINPUT:notepad.manifest kernel32.lib user32.lib gdi32.lib comdlg32.lib shell32.lib shlwapi.lib comctl32.lib
This project is not merely a tool, but a pedagogical instrument for:
Reverse Engineering Training:
Malware Analysis Research:
Operating Systems Study:
notepad/
├── bin/ # Compiled executables
│ ├── Notepad_x86.exe # 32-bit executable (~18 KB)
│ └── Notepad_x64.exe # 64-bit executable (~20 KB)
├── x86/ # 32-bit source files
│ ├── main.asm # Entry point, WinMain, WndProc
│ ├── file.asm # File operations (New, Open, Save, Print)
│ ├── edit.asm # Edit functions (Find, Replace, Status Bar)
│ ├── data.inc # Data structures, constants, variables
│ ├── proto.inc # Function prototypes, API declarations
│ ├── notepad.rc # Resource script (manifest reference)
│ └── notepad.manifest # Application manifest (DPI awareness, etc.)
├── x64/ # 64-bit source files
│ ├── main.asm # Entry point, WinMain, WndProc (x64 ABI)
│ ├── file.asm # File operations (x64 calling convention)
│ ├── edit.asm # Edit functions (x64 calling convention)
│ ├── data.inc # Data structures (64-bit handles, alignment)
│ ├── proto.inc # Function prototypes (EXTERN declarations)
│ ├── notepad.rc # Resource script
│ └── notepad.manifest # Application manifest
├── build.ps1 # Automated build pipeline
├── LICENSE.md # MIT License
└── README.md # Documentation
MIT License. Free for academic, personal, and commercial use. Attribution to the original author is appreciated but not mandatory.
Marek Wesolowski
Project Repository: https://github.com/wesmar/notepad