FreshLib Beginner Tutorial Series

0
#
(ツ) Guest
Last edited: 27.12.25 15:39 by Guest
22
27.12.25 15:32

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

  1. FASM (Flat Assembler) - Version 1.73+

       # Install or download from https://flatassembler.net/
       fasm -version  # Should show 1.73+
    
  1. FreshLib Framework

    • Location: ~/Documents/fossil/FreshIDE/freshlib/

    • Contains all data structures and procedures

  1. 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 strings

  • demo02_string_concat.asm - Concatenate, copy, and get length

  • demo03_string_compare.asm - Compare strings with CF flag

  • demo04_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 capacity

  • demo06_string_substring.asm - Extract, copy, split, trim

  • demo07_string_case.asm - Convert case

  • demo08_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 bases

  • demo10_string_encoding.asm - URL and HTML encoding

  • demo11_string_patterns.asm - Wildcard pattern matching

  • demo12_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 TText

  • demo14_ttext_insert.asm - Insert strings, bytes, characters

  • demo15_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 search

  • demo17_ttext_unicode.asm - UTF-8 index/position conversion

  • demo18_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, iteration

  • demo21_hashtable_basics.asm - Static lookup table with Pearson's hash

    Key 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 TText

  • demo23_json_template.asm - JSON escaping for untrusted data

    Key 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, endp

  • Data declaration: iglobal, uglobal, endg, text, txt

  • Calling convention: stdcall and return patterns

  • Local variables: Stack-based locals in procedures

  • Error handling: Using CF (carry flag) for status

    Demos:

  • demo24_proc_basics.asm - Procedure creation, parameters, locals, error returns

  • demo25_data_macros.asm - Data declaration patterns with iglobal/uglobal

    Key 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 34 for the double quote character: <'Say ', 34, 'Hello', 34> produces Say "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, endobj macros

  • Fields: Private data storage within objects

  • Methods: Object procedures with implicit .self argument

  • Parameters: Properties with getter/setter support

  • Inheritance: Parent-child object relationships

  • Polymorphism: Same method call, different behavior

  • Type checking: Runtime type identification with istype

    Demos:

  • demo26_object_basics.asm - Object creation, methods, destruction

  • demo27_inheritance.asm - Parent/child objects, method override, polymorphism

  • demo28_parameters.asm - Properties with get/set macros

    Key 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 begin

  • Use return instead of ret


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.asm for 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.so is present

  • Run with options.DebugMode = 1 for 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

FreshLib Beginner Tutorial Series

0
#