In this tutorial, we dive into how structured data (specifically JSON) is handled in high-performance assembly web applications. We'll focus on the "AsmBB way," which prioritizes speed and efficiency by avoiding heavy libraries in favor of optimized manual construction and template-driven escaping.
Topics Covered
Manual JSON Building - Using TText (Gap Buffer) for speed.
The cHeadersJSON Constant - Standardizing API responses.
JSON Escaping - Understanding the [json:] template command.
API Patterns - Structuring key-value pairs in assembly.
Manual JSON Building with TText
FreshLib doesn't provide a high-level JSON library. Instead, the most efficient way to generate JSON is using the TText gap buffer. This allows for rapid concatenation without the overhead of complex object models.
The Response Pattern
In AsmBB, API responses are typically built in a TText object and sent directly back to the client.
stdcall TextCreate, sizeof.TText
stdcall TextCat, eax, cHeadersJSON ; "Content-Type: application/json\r\n\r\n"
mov edi, eax ; Save destination
stdcall TextCat, edi, txt '{"status":"ok","id":'
stdcall NumToStr, ebx, ntsDec or ntsUnsigned
stdcall TextCat, edi, eax
stdcall StrDel, eax
stdcall TextCat, edi, txt '}'
JSON Escaping & Templates
When working with user-provided data, escaping special characters (like quotes and backslashes) is critical. AsmBB handles this through a specialized command in its template engine.
Implementation Details:
The command scans the input string and replaces problematic characters with their escaped equivalents (\", \, \/, \b, \t, \n, \f, \r).
Practical API Dispatching
Efficiently routing requests to different JSON-generating procedures is done using the Pearson's hash pattern covered in Tutorial 07.
Demonstrates building a nested JSON object manually using TText. Shows how to handle numbers, strings, and boolean values efficiently.
Demo 23: JSON Templates
File: demo23_json_template.asm
Demonstrates how the [json:] escaping logic works. This demo includes a simplified version of the AsmBB escaping routine to show how to process untrusted strings for JSON output.
Critical Implementation Notes
Register Preservation: FreshLib procedures do NOT preserve EAX or EDX. Pointers returned by StrPtr, NumToStr, and TextCreate must be saved before calling other procedures.
Pattern: TextAddString Returns New Pointer
TText may be reallocated during operations. Always update your pointer from EDX:
stdcall TextAddString, ebx, -1, json_start
mov ebx, edx ; EDX = potentially new TText pointer
stdcall TextAddString, ebx, -1, json_data
mov ebx, edx ; Update after EVERY call!
Pattern: Passing Bytes to stdcall
stdcall requires dword arguments. Use movzx for byte values:
; ❌ WRONG - Build error: "invalid size of operand"
stdcall TextAddChar, edx, al
; ✅ CORRECT - Use movzx to extend to dword
movzx eax, byte [esi]
stdcall TextAddChar, edx, eax
Pattern: Use Literal File Descriptors
For maximum reliability in demos, use 1 directly for STDOUT:
stdcall FileWriteString, 1, msg ; More reliable than [STDOUT]