FreshLib Beginer Tutorial Series
A comprehensive tutorial series for learning FreshLib capabilities in x86 assembly language.
Overview
This tutorial series covers many functions in FreshLib:
StrLib - String library with handles and smart memory management
TText - Gap-buffer based text editor for efficient editing operations
Data Structures - Dynamic arrays and compile-time hash tables
JSON Construction - High-performance JSON building with TText
Macros - FreshLib macros for clean and maintainable code
Objects & OOP - Object-oriented programming with FreshLib
28 demo programs covering 70+ functions across 10 tutorials.
Prerequisites
Software Required
FASM (Flat Assembler) - Version 1.73+
# Install or download from https://flatassembler.net/ fasm -version # Should show 1.73+
FreshLib Framework
Location:
~/Documents/fossil/FreshIDE/freshlib/Contains all data structures and procedures
Runtime Files
ld-musl-i386.so- musl libc runtime (included in tests directory)
Knowledge Required
Basic x86 assembly language
Understanding of registers (EAX, EBX, ECX, EDX, ESI, EDI, EBP, ESP)
Stack frame concepts (push, pop, call, ret)
Basic data types (bytes, words, double words)
Quick Start
Building a Single Demo
cd tutorials/01-strlib-basics
./build.sh
Building All Tutorials
cd tutorials
./build_all.sh
This will build all 28 demos across 10 tutorials and run tests:
╔═══════════════════════════════════════════════════════════════╗
║ FreshLib Tutorial Series - Master Build Script ║
╚═══════════════════════════════════════════════════════════════╝
Tutorial: 01-strlib-basics ... ✓
Tutorial: 02-strlib-manipulation ... ✓
...
╔═══════════════════════════════════════════════════════════════╗
║ Summary ║
╠═══════════════════════════════════════════════════════════════╣
║ Total demos passed: 28 ║
║ Tutorials with errors: 0 ║
╚═══════════════════════════════════════════════════════════════╝
Running a Demo
cd 01-strlib-basics
./demo01_string_create
Tutorial Roadmap
| Tutorial | Topic | Demos | Functions Covered |
| 01 | StrLib Basics | 4 | String creation, concatenation, comparison, search |
| 02 | StrLib Manipulation | 4 | String modification, substrings, case, trim |
| 03 | StrLib Advanced | 4 | Numbers, encoding, patterns, hash |
| 04 | TText Basics | 3 | Gap buffer creation, insertion, deletion |
| 05 | TText Advanced | 3 | Searching, Unicode, coordinates |
| 06 | TText Real-World | 1 | Complete working example |
| 07 | Data Structures | 2 | Vector (TArray), HashTable (Pearson's) |
| 08 | JSON Serialization | 2 | Manual construction, template escaping |
| 09 | Macros | 2 | proc/endp, iglobal/uglobal, stdcall |
| 10 | Objects & OOP | 3 | object/endobj, inheritance, polymorphism |
Tutorial 01: StrLib Basics
Topics:
String structure (capacity, len, data)
Handles vs pointers
Creating, duplicating, and deleting strings
Getting string pointers
String concatenation and length
String comparison (case-sensitive/insensitive)
Searching within strings
Demos:
demo01_string_create.asm- Create, duplicate, and delete stringsdemo02_string_concat.asm- Concatenate, copy, and get lengthdemo03_string_compare.asm- Compare strings with CF flagdemo04_string_search.asm- Find characters and substrings
Tutorial 02: StrLib - String Manipulation
Topics:
String modification (insert, append)
Substring operations (extract, split, trim)
Case conversion (uppercase, lowercase)
Whitespace handling
Quote handling
Memory management
Demos:
demo05_string_modify.asm- Insert, append, expand capacitydemo06_string_substring.asm- Extract, copy, split, trimdemo07_string_case.asm- Convert casedemo08_string_trim.asm- Handle whitespace and quotes
Tutorial 03: StrLib - Advanced Features
Topics:
Number conversion (string ↔ number)
URL and HTML encoding/decoding
Pattern matching with wildcards
Hash functions
Sort comparison
Demos:
demo09_string_numbers.asm- Number conversion in all basesdemo10_string_encoding.asm- URL and HTML encodingdemo11_string_patterns.asm- Wildcard pattern matchingdemo12_string_hash.asm- Hash computation and sort comparison
Tutorial 04: TText - Gap Buffer Basics
Topics:
What is a gap buffer?
TText structure layout (backward structure)
Three coordinate systems (offset, position, index)
Creating and freeing TText
Inserting and deleting text
Demos:
demo13_ttext_create.asm- Create, duplicate, debug TTextdemo14_ttext_insert.asm- Insert strings, bytes, charactersdemo15_ttext_delete.asm- Delete characters and compact
Tutorial 05: TText - Advanced Operations
Topics:
Searching with KMP algorithm
UTF-8 character handling
Coordinate conversion
Helper macros
Demos:
demo16_ttext_search.asm- KMP-based substring searchdemo17_ttext_unicode.asm- UTF-8 index/position conversiondemo18_ttext_coords.asm- Offset/position/index conversion
Tutorial 06: TText - Real-World Patterns
Topics:
Common usage patterns from AsmBB
Building HTTP responses
Integration with StrLib
Demos:
demo19_ttext_advanced.asm- Comprehensive real-world example
Tutorial 07: Data Structures (Vector & HashTable)
FreshLib provides dynamic arrays (TArray/vectors) and compile-time hash tables for efficient data management.
Topics:
TArray structure: Dynamic arrays with automatic resizing
Element lifecycle: CreateArray, AddArrayItems, DeleteArrayItems
Array iteration: Accessing elements via count and array pointer
PHashTable: Compile-time perfect hash tables
Pearson's hash: Fast case-insensitive string lookup
Demos:
demo20_vector_basics.asm- Dynamic array creation, adding items, iterationdemo21_hashtable_basics.asm- Static lookup table with Pearson's hashKey Functions:
| Function | Purpose | Returns |
CreateArray, itemSize | Create dynamic array | EAX = TArray pointer |
AddArrayItems, pArray, count | Add items to array | EAX = ptr to new items, EDX = new TArray |
DeleteArrayItems, pArray, idx, count | Remove items | EDX = new TArray |
DestroyArray, pArray | Free array memory | - |
TArray Structure:
; TArray structure layout
struct TArray
.count dd ? ; Number of elements
.capacity dd ? ; Allocated capacity
.itemSize dd ? ; Size of each element
.array dd ? ; Start of data (variable size)
ends
; Accessing array elements
mov ebx, [edx+TArray.count] ; Get element count
lea esi, [edx+TArray.array] ; Get pointer to first element
mov eax, [esi + ecx*4] ; Access element at index ECX
PHashTable Pattern (from asmBB):
; Define compile-time hash table
PHashTable tableCommands, tpl_func, \
"help", cmdHelp, \
"list", cmdList, \
"delete", cmdDelete
; Runtime lookup
stdcall GetHashTableItem, tableCommands, hCommandString
test eax, eax
jz .not_found
call eax ; Call the matched function
AsmBB Usage Examples:
; From attachments.asm - iterating file uploads
mov esi, eax ; TArray of TPostFileItem
mov ebx, [esi+TArray.count]
lea esi, [esi+TArray.array]
.loop:
dec ebx
js .done
; Process item at [esi + ebx*sizeof.TPostFileItem]
jmp .loop
; From commands.asm - parameter lookup
cmp [edx+TArray.count], 0
je .no_params
mov eax, [edx+TArray.array] ; Get first parameter
Tutorial 08: JSON Construction & the "AsmBB Way"
Learn high-performance JSON serialization patterns used in AsmBB's REST API.
Topics:
TText for JSON: Using gap buffer for efficient string building
Manual construction: Building JSON piece by piece
JSON escaping: Safe handling of special characters
Content-Type headers: Proper HTTP response formatting
API patterns: Command dispatch and response structure
Demos:
demo22_json_manual.asm- Manual JSON building using TTextdemo23_json_template.asm- JSON escaping for untrusted dataKey Functions:
| Function | Purpose | Returns |
TextCreate, size | Create TText buffer | EAX = TText pointer |
TextAddString, pText, pos, str | Add string at position | EDX = new TText |
TextCompact, pText | Remove gap for output | - |
TextFree, pText | Free TText memory | - |
JSON Building Pattern:
; Create JSON response
stdcall TextCreate, 1024
mov ebx, eax
; Add content
stdcall TextAddString, ebx, -1, txt '{"status":"success",'
mov ebx, edx
stdcall TextAddString, ebx, -1, txt '"data":{'
mov ebx, edx
; Add dynamic value
stdcall TextAddString, ebx, -1, txt '"message":"'
mov ebx, edx
stdcall TextAddString, ebx, -1, [hUserMessage]
mov ebx, edx
stdcall TextAddString, ebx, -1, txt '"}}'
mov ebx, edx
; Output
stdcall TextCompact, ebx
stdcall FileWriteString, [STDOUT], ebx
stdcall TextFree, ebx
JSON Escaping Pattern:
; Escape special characters for JSON safety
proc JsonEscape, .hStr
begin
; Escape: " -> \" \ -> \\ newline -> \n etc.
stdcall StrLen, [.hStr]
shl eax, 1 ; Allocate 2x for safety
stdcall TextCreate, eax
; ... character-by-character escaping ...
return
endp
AsmBB API Response Pattern:
; From api.asm - Standard JSON response
stdcall TextCreate, 2048
mov ebx, eax
; HTTP headers
stdcall TextAddString, ebx, -1, txt "Content-Type: application/json", 13, 10, 13, 10
mov ebx, edx
; JSON body
stdcall TextAddString, ebx, -1, txt '{"result":'
mov ebx, edx
; ... add data ...
; Send response
stdcall TextCompact, ebx
stdcall FileWriteString, [STDOUT], ebx
Tutorial 09: FreshLib Macros & Coding Style
Master the essential macros that make FreshLib assembly code clean and maintainable.
Topics:
Procedure macros:
proc,begin,return,endpData declaration:
iglobal,uglobal,endg,text,txtCalling convention:
stdcalland return patternsLocal variables: Stack-based locals in procedures
Error handling: Using CF (carry flag) for status
Demos:
demo24_proc_basics.asm- Procedure creation, parameters, locals, error returnsdemo25_data_macros.asm- Data declaration patterns with iglobal/uglobalKey Macros:
| Macro | Purpose | Example |
proc Name, .arg1, .arg2 | Define procedure with parameters | proc AddNumbers, .a, .b
|
.local dd ? | Declare local variable | .result dd ?
|
begin | Start procedure body | Required after proc |
return | Exit procedure (handles stack) | Use instead of ret
|
endp | End procedure definition | Pairs with proc
|
iglobal...endg | Initialized data section | Takes binary space |
uglobal...endg | Uninitialized data (BSS) | No binary space |
text "str" | Define null-terminated string | In iglobal block |
txt "str" | Inline string constant | For function arguments |
<"str", 13, 10> | Inline string with escape codes | <"Hello!", 13, 10>
|
<'str', 13, 10> | Same with single quotes | <'Has "quotes"', 13, 10>
|
stdcall func, args | Call with cdecl cleanup | Callee cleans stack |
Tip: Use single quotes when the string contains double quotes, or use ASCII code
34for the double quote character:<'Say ', 34, 'Hello', 34>producesSay "Hello"
text vs txt - What's the Difference?
| Feature | text "str" | txt "str"
|
| Context | Inside iglobal/endg | Inline in function calls |
| Label | Named (you define it) | Anonymous (auto-generated) |
| Reusability | Reference label multiple times | One-time use |
| Deduplication | Yes (identical strings stored once) | Yes (same mechanism) |
; text: Named label in iglobal block (reusable)
iglobal
cMessage text "Hello, World!" ; Named label 'cMessage'
endg
stdcall FileWriteString, [STDOUT], cMessage
stdcall FileWriteString, [STDOUT], cMessage ; Reuse same label
; txt: Anonymous inline string (one-off convenience)
stdcall FileWriteString, [STDOUT], txt "Quick message"
; <...>: FASM native syntax with escape codes
stdcall FileWriteString, [STDOUT], <"Line with CRLF", 13, 10>
Procedure Pattern:
proc MyFunction, .param1, .param2
.localVar dd ? ; Local variable
.buffer rb 256 ; Local buffer
begin
pushad ; Preserve all registers
mov eax, [.param1]
add eax, [.param2]
mov [.localVar], eax
; Set return value before popad
mov [esp+4*regEAX], eax
clc ; Success (CF=0)
popad
return
endp
Data Declaration Pattern:
; Initialized data (in binary)
iglobal
cAppName text "My Application"
cVersion text "1.0.0"
nMaxItems dd 1024
aDefaults dd 10, 20, 30, 40
endg
; Uninitialized data (BSS - no binary space)
uglobal
hMainHandle dd ?
szBuffer rb 4096
pTempPtr dd ?
endg
Error Handling Pattern:
; Function with error handling
proc SafeDivide, .dividend, .divisor
begin
mov eax, [.divisor]
test eax, eax
jz .error ; Division by zero
mov eax, [.dividend]
cdq
idiv dword [.divisor]
clc ; Success: CF=0
return
.error:
xor eax, eax
stc ; Error: CF=1
return
endp
; Calling code
stdcall SafeDivide, 100, 5
jc .handle_error ; Check CF for error
; EAX contains result
Tutorial 10: Objects & OOP
FreshLib provides a complete object-oriented programming system for assembly language, including classes (objects), inheritance, polymorphism, and properties.
Topics:
Object definition:
object,endobjmacrosFields: Private data storage within objects
Methods: Object procedures with implicit
.selfargumentParameters: Properties with getter/setter support
Inheritance: Parent-child object relationships
Polymorphism: Same method call, different behavior
Type checking: Runtime type identification with
istypeDemos:
demo26_object_basics.asm- Object creation, methods, destructiondemo27_inheritance.asm- Parent/child objects, method override, polymorphismdemo28_parameters.asm- Properties with get/set macrosKey Macros:
| Macro | Purpose | Example |
object Name, Parent | Define object type | object TCat, TAnimal
|
endobj | End object definition | Required after object |
method .Name, args | Declare a method | method .Speak
|
param .Name, get, set | Declare property | param .Age, ._age, ._age
|
create target, Type, args | Create object instance | create [pCat], TCat, "Whiskers"
|
destroy obj | Destroy object | destroy [pCat]
|
exec obj, Type:Method, args | Call method | exec [pCat], TCat:Speak
|
get target, obj, Type:Param | Get property | get eax, [pRect], TRect:Width
|
set obj, Type:Param, value | Set property | set [pRect], TRect:Width, 100
|
istype obj, Type | Check type (ZF) | istype [pCat], TAnimal
|
Object Definition Pattern:
object TAnimal
; Fields (private data)
.name dd ?
.age dd ?
; Parameters (properties)
param .Age, ._age, ._age ; Direct field access
param .Name, .GetName, NONE ; Read-only via method
; Methods
method .Create, .pName, .nAge
method .Destroy
method .Speak
endobj
; Method implementation
method TAnimal.Speak
begin
pushad
; .self is implicitly available
mov esi, [.self]
; ... method code ...
popad
return
endp
Inheritance Pattern:
object TDog, TAnimal ; TDog inherits from TAnimal
; Additional fields
.breed dd ?
; Override parent method
method .Speak ; Same name = override
; New methods
method .Fetch
endobj
AsmBB Reference Patterns:
The FreshLib object system is used internally for GUI components. In asmBB (server-side), similar patterns are used with structures:
; From asmbb/source/commands.asm
struct TSpecialParams
.hJSON dd ?
.pPostData dd ?
.pPostFiles dd ?
ends
; From asmbb/source/post_data.asm
struct TPostDataItem
.hKey dd ?
.hValue dd ?
ends
; Usage with TArray (dynamic arrays)
mov ebx, [esi+TArray.count]
lea esi, [esi+TArray.array]
See also: FreshLib documentation at freshlib/_doc/real_objects.md
File Structure
tutorials/
├── README.md # This file
├── build_all.sh # Master build script (builds all tutorials)
├── 01-strlib-basics/
│ ├── tutorial.md # Tutorial documentation
│ ├── build.sh # Build script
│ └── demo*.asm # Demo programs
├── 02-strlib-manipulation/
│ └── ...
└── ...
Coding Style Guide
All demos follow FreshLib/AsmBB coding conventions, which ensure consistency and compatibility with the AsmBB codebase.
File Structure Template
Every ASM file should follow this structure:
; _______________________________________________________________________________________
;| |
;| ..:: FreshLib Tutorials ::.. |
;|_______________________________________________________________________________________|
;
; Description: Brief description of what this file does.
;_________________________________________________________________________________________
include "%lib%/freshlib.inc"
LINUX_INTERPRETER equ './ld-musl-i386.so'
@BinaryType console, compact
LIB_MODE equ NOGUI
options.DebugMode = 0
include "%lib%/freshlib.asm"
; ========================================
; Initialized Data
; ========================================
iglobal
cMessage text "Hello", 13, 10
nValue dd 42
endg
; ========================================
; Uninitialized Data
; ========================================
uglobal
hHandle dd ?
szBuffer rb 256
endg
; ========================================
; Entry Point
; ========================================
start:
InitializeAll
; ... code ...
FinalizeAll
stdcall TerminateAll, 0
Data Declaration Conventions
| Block | Purpose | Binary Impact | Example |
iglobal...endg | Initialized data | Takes space in binary | cMsg text "Hello"
|
uglobal...endg | Uninitialized data | No space (BSS) | hHandle dd ?
|
String Declaration:
; CORRECT: Use 'text' macro in iglobal
iglobal
cMessage text "Hello, World!", 13, 10
cCRLF text 13, 10
endg
; INCORRECT: Bare 'db' statements
msg_hello: db "Hello", 0 ; Don't do this!
Console Output
Always use [STDOUT] instead of literal 1:
; CORRECT:
stdcall FileWriteString, [STDOUT], cMessage
; INCORRECT:
stdcall FileWriteString, 1, cMessage ; Don't use literal 1!
Procedure Conventions
; Standard procedure template
proc MyFunction, .param1, .param2
.localVar dd ? ; Local variables after parameters
begin
; Preserve registers if needed
pushad
mov eax, [.param1]
add eax, [.param2]
mov [.localVar], eax
; Restore and return
mov [esp+4*regEAX], eax ; Set return value
popad
return
endp
Key Rules:
Use
proc/begin/return/endp(not raw labels)Parameters start with
.(e.g.,.param1)Local variables declared between proc line and
beginUse
returninstead ofret
FreshLib Code Conventions
The following conventions are from the official FreshLib documentation.
Naming Conventions
1. Underscore Prefix Convention
Names prefixed with underscores are not recommended for user code. These are internally used labels that may change:
| Prefix | Meaning | Example |
_ (one) | Use carefully - semi-internal | _AlmostPrivate
|
__ (two) | Internal - avoid using | __MorePrivate
|
___ (three) | Do not use - will change! | ___SomeVeryPrivateLabel
|
Rule: More underscores = more "internal" the identifier. Three underscores means it's for internal use only and will be changed later.
2. Code Completion Friendly
Names are designed for code completion editors:
No long equal prefixes
Short "class" prefixes group related functions
Examples:
Str*— String library functions (StrNew,StrDup,StrLen)Text*— TText functions (TextCreate,TextAddString)File*— File operations (FileRead,FileWrite)
3. CamelCase Convention
| Type | Style | Example |
| Constants | lowerCamelCase | ntsHex, tsfCaseSensitive
|
| Procedures | UpperCamelCase | StrCompare, TextCreate
|
4. Local Labels and Arguments
All local labels and procedure arguments are prefixed with dot (.):
proc MyFunction, .param1, .param2 ; Arguments with dot prefix
.localVar dd ? ; Local variable with dot prefix
begin
mov eax, [.param1] ; Access via dot prefix
jz .error ; Local label with dot prefix
; ...
.error:
; ...
return
endp
5. Struct and Object Definitions
All struct and object definitions are prefixed with T:
| Type | Prefix | Example |
| Structures | T | TTimer, TButton, TText, TArray
|
| Objects | T | TWindow, TEdit
|
struct TMyStruct
.field1 dd ?
.field2 dd ?
ends
6. File Name Convention
| Extension | Contents | Example |
.inc | Only macros and constants (no code/data) | freshlib.inc
|
.asm | Code and data definitions | strlib.asm
|
Important: Code and data in FreshLib only exist in the compiled binary if they are used. Unused code/data appearing in the binary should be considered a bug.
Register Preserving Convention
1. Preserve All You Use
The rule: All procedures in FreshLib preserve all registers, except those used for returning result values.
proc MyFunction, .param
begin
pushad ; Preserve ALL registers
; ... do work ...
mov [esp+4*regEAX], eax ; Set return value before popad
popad ; Restore all registers
return
endp
Note: Some object handling procedures preserve registers internally, so users may not need to preserve them. See
object.asmfor details.
2. Carry Flag (CF) for Error Status
CF is widely used for returning error status or boolean results:
| CF Value | Meaning |
CF=0 (clc) | Success / No error |
CF=1 (stc) | Error occurred |
stdcall SomeFunction, arg1
jc .error ; CF=1 means error
; success path...
.error:
; error handling...
Note: The use of CF is always described in the documentation of respective procedures.
3. Return Register Convention
Procedures can return results in more than one register:
| Register | Purpose | Example |
| EAX | Primary return value (32-bit) | Most procedures |
| EDX | Secondary value, or with EAX for 64-bit | X,Y coordinates; TText pointer |
| ECX | Count/size of data | LoadBinaryFile returns pointer in EAX, size in ECX
|
Examples:
; Example 1: Simple return
stdcall StrLen, hString
; EAX = string length
; Example 2: Multiple returns (coordinates)
stdcall GetPosition
; EAX = X coordinate
; EDX = Y coordinate
; Example 3: Pointer + Size
stdcall LoadBinaryFile, cFilename
; EAX = pointer to data
; ECX = data size
jc .load_error
Comment Style
; ========================================
; Section Header
; ========================================
mov eax, [.param] ; Get parameter value
test eax, eax ; Check if NULL
jz .error ; Jump if error
; Multi-line block comment explaining
; complex logic goes here
stdcall ProcessData, eax
Quick Reference: Common Prefixes
| Prefix | Meaning | Example |
c | Constant (iglobal) | cMessage, cTitle
|
s | Static string | sUserName
|
h | Handle | hString, hFile
|
p | Pointer | pText, pBuffer
|
n | Number | nCount, nValue
|
f | Flag/Boolean | fEnabled
|
T | Type/Struct | TText, TArray
|
_ | Semi-internal | _AlmostPrivate
|
___ | Do not use! | ___InternalOnly
|
Function Reference
A complete function reference is included in each demo's FUNCTION REFERENCE comment block, describing:
Function purpose
Arguments with types
Return values (registers)
Carry flag status
Important notes and warnings
Build Output
Each build script shows:
Building demo01_string_create... ✓
Testing demo01_string_create... ✓ Runs OK
...
Build complete: 4 passed, 0 failed
Runtime Requirements
All demos require ld-musl-i386.so in the same directory. The build scripts automatically copy this from the tests directory.
Troubleshooting
"ld-musl-i386.so: No such file or directory"
# Copy runtime file manually
cp ../tests/ld-musl-i386.so .
"fasm: command not found"
# Install FASM or add to PATH
export PATH=$PATH:/path/to/fasm
Demo crashes immediately
Check that FreshLib path is correct in build.sh
Verify
ld-musl-i386.sois presentRun with
options.DebugMode = 1for more info
Further Reading
FreshLib Source:
~/Documents/fossil/FreshIDE/freshlib/AsmBB Source:
~/Documents/fossil/asmbb/source/FreshLib Documentation:
freshlib/_doc/data.wiki
License
This tutorial series is part of the AsmBB project and follows the same license.
Ready to learn? Start with Tutorial 01: StrLib Basics