### Fluent API Encoding Example Source: https://github.com/xoofx/asmarm64/blob/main/doc/readme.md Implementation of the assembly loop using the C# fluent Arm64Assembler API. ```csharp using static Arm64Factory; using var asm = new Arm64Assembler(0x1_0000); // Main entry point // _start: asm.Label("_start", out var labelStart); // mov x0, #5 // Call sum_loop(5) // bl sum_loop // Call the function, result in x0 // ret // Return from _start (normally would return to a caller) var labelSumLoop = asm.CreateLabel("sum_loop"); asm.MOVZ(X0, 5) .BL(labelSumLoop) .RET(); // // // // Function: sum_loop(x0) // // - Takes x0 as the loop limit // // - Returns the sum in x0 // sum_loop: asm.Label(labelSumLoop); // mov x1, #0 // Accumulator (sum) // mov x2, #0 // Counter asm.MOVZ(X1, 0) .MOVZ(X2, 0); // // loop_start: asm.Label("loop_start", out var labelLoopStart); // add x1, x1, x2 // Add counter (x2) to sum (x1) // add x2, x2, #1 // Increment counter // cmp x2, x0 // Compare counter with limit // blt loop_start // If counter < limit, continue loop // mov x0, x1 // Store result in x0 (return value) // ret // Return to caller asm.ADD(X1, X1, X2) .ADD(X2, X2, 1) .CMP(X2, X0) .B(LT, labelLoopStart) .MOV(X0, X1) .RET() .End(); ReadOnlySpan code = asm.Buffer; ``` -------------------------------- ### ARM64 Assembly Source Example Source: https://github.com/xoofx/asmarm64/blob/main/doc/readme.md Example assembly code representing a loop that calculates a sum. ```asm _start: mov x0, #5 // Call sum_loop(5) bl sum_loop // Call the function, result in x0 // Do something with result (for now, just returning) ret // Return from _start (normally would return to a caller) // Function: sum_loop(x0) // - Takes x0 as the loop limit // - Returns the sum in x0 sum_loop: mov x1, #0 // Accumulator (sum) mov x2, #0 // Counter loop_start: add x1, x1, x2 // Add counter (x2) to sum (x1) add x2, x2, #1 // Increment counter cmp x2, x0 // Compare counter with limit blt loop_start // If counter < limit, continue loop mov x0, x1 // Store result in x0 (return value) ret // Return to caller ``` -------------------------------- ### Build and Test the Project Source: https://github.com/xoofx/asmarm64/blob/main/AGENTS.md Commands to build and test the library from the project root. ```sh # from the project root (this folder) cd src dotnet build -c Release dotnet test -c Release ``` -------------------------------- ### Implement forward branches in AsmArm64 Source: https://github.com/xoofx/asmarm64/blob/main/doc/convert_arm64_to_csharp.md Shows how to handle conditional branching and labels in C#. ```asm cbz x0, done add x0, x0, #1 done: ret ``` ```csharp asm.CBZ(X0, out var done) .ADD(X0, X0, 1) .Label(done) .RET() .End(); ``` -------------------------------- ### Implement a loop in AsmArm64 Source: https://github.com/xoofx/asmarm64/blob/main/doc/convert_arm64_to_csharp.md Demonstrates translating a sum loop assembly pattern into a fluent C# builder pattern. ```asm sum_loop: mov x1, #0 mov x2, #0 loop: add x1, x1, x2 add x2, x2, #1 cmp x2, x0 b.lt loop mov x0, x1 ret ``` ```csharp using static AsmArm64.Arm64Factory; using var asm = new Arm64Assembler(0x1000); asm.BeginFunction("sum_loop") .Label(out var sumLoop) .MOVZ(X1, 0) .MOVZ(X2, 0) .Label(out var loop) .ADD(X1, X1, X2) .ADD(X2, X2, 1) .CMP(X2, X0) .B(LT, loop) .MOV(X0, X1) .RET() .EndFunction("sum_loop") .End(); ``` -------------------------------- ### Use Strongly Typed Assembler API Source: https://github.com/xoofx/asmarm64/blob/main/readme.md Demonstrates creating an assembler instance, defining labels, and chaining instruction methods to generate ARM64 machine code. ```c# using var asm = new Arm64Assembler(0x1_0000); // // Main entry point // _start: asm.Label("_start", out var labelStart); // mov x0, #5 // Call sum_loop(5) // bl sum_loop // Call the function, result in x0 // ret // Return from _start (normally would return to a caller) var labelSumLoop = asm.CreateLabel("sum_loop"); asm.MOVZ(X0, 5) .BL(labelSumLoop) .RET(); // // // // Function: sum_loop(x0) // // - Takes x0 as the loop limit // // - Returns the sum in x0 // sum_loop: asm.Label(labelSumLoop); // mov x1, #0 // Accumulator (sum) // mov x2, #0 // Counter asm.MOVZ(X1, 0) .MOVZ(X2, 0); // // loop_start: asm.Label("loop_start", out var labelLoopStart); // add x1, x1, x2 // Add counter (x2) to sum (x1) // add x2, x2, #1 // Increment counter // cmp x2, x0 // Compare counter with limit // blt loop_start // If counter < limit, continue loop // mov x0, x1 // Store result in x0 (return value) // ret // Return to caller asm.ADD(X1, X1, X2) .ADD(X2, X2, 1) .CMP(X2, X0) .B(LT, labelLoopStart) .MOV(X0, X1) .RET() .End(); // Bytes available in asm.Buffer or asm.ToArray() ``` -------------------------------- ### Handle Assembler Diagnostics Source: https://github.com/xoofx/asmarm64/blob/main/doc/readme.md Use TryEnd to validate label patches and retrieve structured diagnostic information when assembly fails. ```csharp using var asm = new Arm64Assembler(0x1000); asm.B(out var missing); if (!asm.TryEnd(out var diagnostics)) { foreach (var diagnostic in diagnostics) { Console.WriteLine(diagnostic); } } ``` -------------------------------- ### Importing the Arm64Factory Source: https://github.com/xoofx/asmarm64/blob/main/doc/readme.md Include this static using directive to access registers and factory methods directly. ```c# // Add this using directive at the beginning of your file using static AsmArm64.Arm64Factory; ``` -------------------------------- ### JIT compile-time constant encoding Source: https://github.com/xoofx/asmarm64/blob/main/doc/readme.md Demonstrates how instructions are encoded as constants during JIT compilation. ```c# public static uint Tester() { return Arm64InstructionFactory.MOVZ(X0, 5); } ``` ```asm ; Method Tester():uint (FullOpts) G_M000_IG01: ;; offset=0x0000 G_M000_IG02: ;; offset=0x0000 mov eax, 0xFFFFFFFFD28000A0 G_M000_IG03: ;; offset=0x0005 ret ; Total bytes of code: 6 ``` -------------------------------- ### Use Disassembler API Source: https://github.com/xoofx/asmarm64/blob/main/readme.md Shows how to disassemble a buffer of instructions into a text writer or string, including quick roundtrip methods. ```c# ReadOnlySpan instructionBuffer = asm.Buffer; var disassembler = new Arm64Disassembler(); var textWriter = new StringWriter(); disassembler.Disassemble(instructionBuffer, textWriter); Console.WriteLine(textWriter); // For quick roundtrips, use: string text = asm.Disassemble(); // or: string text2 = Arm64Disassembler.DisassembleToString(instructionBuffer, asm.BaseAddress); ``` -------------------------------- ### Define raw data and alignment Source: https://github.com/xoofx/asmarm64/blob/main/doc/convert_arm64_to_csharp.md Use Align and BeginDataSection to manage memory layout and constants. ```csharp asm.Align(16) .BeginDataSection("constants") .AppendUInt64(0x1122334455667788UL) .EndDataSection(); ``` -------------------------------- ### Disassemble with custom symbols Source: https://github.com/xoofx/asmarm64/blob/main/doc/convert_arm64_to_csharp.md Configure the Arm64Disassembler with a custom label formatter. ```csharp var text = new Arm64Disassembler { Options = { BaseAddress = (long)asm.BaseAddress, TryFormatLabel = (address, destination, out int written) => { if ((ulong)address == loop.Address) return destination.TryWrite("loop", out written); written = 0; return false; } } }.Disassemble(asm.Buffer); ``` -------------------------------- ### Encoding a single instruction Source: https://github.com/xoofx/asmarm64/blob/main/doc/readme.md Use Arm64InstructionFactory to encode instructions into raw values. ```c# var rawValue = Arm64InstructionFactory.MOVZ(X0, 5); // Prints "0xD28000A0" Console.WriteLine($"0x{rawValue:X8}"); ``` -------------------------------- ### Customize disassembler formatting Source: https://github.com/xoofx/asmarm64/blob/main/doc/readme.md Apply a preset style and customize label formats, prefixes, and hex casing via disassembler options. ```csharp var disassembler = new Arm64Disassembler { Options = { Style = Arm64DisassemblyStyle.Gas, LocalLabelFormat = ".L{0}", CommentPrefix = ";", AddressPrefix = "0x", UseUppercaseHex = false } }; ``` -------------------------------- ### Arrange blocks with fixed and floating layout Source: https://github.com/xoofx/asmarm64/blob/main/doc/readme.md Use Arm64Block with ArrangeBlocks to define fixed memory addresses or floating blocks with specific alignment. ```csharp var data = asm.CreateLabel("data"); asm.ArrangeBlocks(new Arm64Block(data, [1, 2, 3, 4], alignment: 4, address: 0x2000)); ``` -------------------------------- ### Annotate Disassembly with Debug Map Source: https://github.com/xoofx/asmarm64/blob/main/doc/readme.md Implement TryFormatComment to map instruction offsets to source file and line information stored in the DebugMap. ```csharp var disassembler = new Arm64Disassembler { Options = { BaseAddress = (long)asm.BaseAddress, TryFormatComment = (offset, instruction, destination, out int written) => { var entry = asm.DebugMap?.Entries.LastOrDefault(x => x.Offset == (uint)offset); if (entry is { FilePath: not null }) { return destination.TryWrite($"{Path.GetFileName(entry.FilePath)}:{entry.LineNumber}", out written); } written = 0; return false; } } }; ``` -------------------------------- ### Defining and using labels Source: https://github.com/xoofx/asmarm64/blob/main/doc/migration-2.0.md Prefer object-based labels over label IDs for better readability and type safety. ```csharp asm.Label(out var loop) .ADD(X0, X0, 1) .B(loop) .End(); ``` ```csharp var id = asm.CreateLabelId("loop"); asm.BindLabel(id); asm.B(id); ``` ```csharp asm.Label("loop", out var loop); asm.B(loop); ``` -------------------------------- ### Arm64Instruction.Decode Source: https://github.com/xoofx/asmarm64/blob/main/doc/readme.md Decodes a full Arm64Instruction object from the provided bytes. ```APIDOC ## Arm64Instruction.Decode(uint instructionBytes) ### Description Returns an Arm64Instruction object containing detailed information about the instruction. ### Parameters - **instructionBytes** (uint) - Required - The 32-bit instruction bytes in little-endian order. ``` -------------------------------- ### Constructing and finalizing an assembler Source: https://github.com/xoofx/asmarm64/blob/main/doc/migration-2.0.md Use an owned-buffer assembler for simple code generation. End() is the preferred method for finalization over the legacy Assemble() alias. ```csharp using var asm = new Arm64Assembler(0x1000); asm.MOVZ(X0, 1) .RET() .End(); ReadOnlySpan code = asm.Buffer; byte[] stableCopy = asm.ToArray(); ``` -------------------------------- ### Disassemble a sequence of instructions Source: https://github.com/xoofx/asmarm64/blob/main/doc/readme.md Use the Arm64Disassembler class to process a byte buffer and generate a disassembled text representation of the instructions. ```csharp var buffer = new byte[] { 0xA0, 0x00, 0x80, 0xD2, 0xC0, 0x03, 0x5F, 0xD6 }; var disassembler = new Arm64Disassembler(); var text = disassembler.Disassemble(buffer); Console.WriteLine(text); ``` ```asm LL_01: mov x0, #5 ret ``` -------------------------------- ### Configure disassembler auto-labeling Source: https://github.com/xoofx/asmarm64/blob/main/doc/readme.md Set AutoLabelKinds to control which PC-relative operands generate local labels during disassembly. ```csharp var disassembler = new Arm64Disassembler { Options = { AutoLabelKinds = Arm64DisassemblerAutoLabelKind.FirstInstruction | Arm64DisassemblerAutoLabelKind.Branches | Arm64DisassemblerAutoLabelKind.Calls | Arm64DisassemblerAutoLabelKind.ConditionalBranches | Arm64DisassemblerAutoLabelKind.TestCompareBranches } }; ``` -------------------------------- ### Resolve Symbols in Disassembler Source: https://github.com/xoofx/asmarm64/blob/main/doc/readme.md Use the TryFormatLabel hook to resolve absolute addresses to human-readable symbols from external sources. ```csharp var symbols = new Dictionary { [0x1000] = "start", [0x1040] = "loop", }; disassembler.Options.TryFormatLabel = (address, destination, out int written) => { if (symbols.TryGetValue(address, out var name)) { written = name.Length; return name.AsSpan().TryCopyTo(destination); } written = 0; return false; }; ``` -------------------------------- ### Manage literal pools Source: https://github.com/xoofx/asmarm64/blob/main/doc/convert_arm64_to_csharp.md Use the Literal method and FlushLiteralPool to handle constant data pools. ```csharp var literal = asm.Literal(0x1122334455667788UL, "constant"); asm.LDR(X0, literal) .FlushLiteralPool() .End(); ``` -------------------------------- ### Handle external symbols and relocations Source: https://github.com/xoofx/asmarm64/blob/main/doc/readme.md Use ExternalLabel for unresolved symbols and iterate through the Relocations collection to inspect them. ```csharp var puts = asm.ExternalLabel("puts"); asm.BL(puts).End(); foreach (var relocation in asm.Relocations) { Console.WriteLine($"{relocation.Kind} at 0x{relocation.Offset:X}: {relocation.Label.Name}"); } ``` -------------------------------- ### Using register indexers Source: https://github.com/xoofx/asmarm64/blob/main/doc/readme.md Syntax for accessing specific register indices. ```c# Arm64InstructionFactory.BFDOT(V0.T_2S, V1.T_4H, V2.T_2H[1]); // BFDOT V0.2S, V1.4H, V2.2H[1] ``` -------------------------------- ### Perform assembly and disassembly roundtrip Source: https://github.com/xoofx/asmarm64/blob/main/doc/readme.md Disassemble generated code directly from the assembler buffer or use the static helper for standalone byte arrays. ```csharp using var asm = new Arm64Assembler(0x1000); asm.MOVZ(X0, 1) .RET() .End(); string text = asm.Disassemble(); ``` ```csharp string text = Arm64Disassembler.DisassembleToString(code, baseAddress: 0x1000); ``` -------------------------------- ### Materialize addresses Source: https://github.com/xoofx/asmarm64/blob/main/doc/convert_arm64_to_csharp.md Use ADRP and page helpers for page-relative address calculation. ```csharp var symbol = new Arm64Label(0x1234_5678, "symbol"); asm.ADRP(X0, symbol.Page()) .ADD(X0, X0, (uint)symbol.PageOffset().Evaluate()); ``` -------------------------------- ### Record Debug Map Entries Source: https://github.com/xoofx/asmarm64/blob/main/doc/readme.md Use section and function helpers to automatically populate the DebugMap for tracking code and data sections. ```csharp using var asm = new Arm64Assembler(0x1000); asm.BeginFunction("sum") .BeginCodeSection("text") .MOVZ(X0, 5) .RET() .EndCodeSection() .BeginDataSection("rodata") .AppendUInt32(0x12345678) .EndDataSection() .EndFunction("sum") .End(); foreach (var entry in asm.DebugMap!.Entries) { Console.WriteLine(entry); } ``` -------------------------------- ### Format status flag comments Source: https://github.com/xoofx/asmarm64/blob/main/doc/readme.md Implement TryFormatComment to inject custom status flag information into the disassembly output. ```csharp disassembler.Options.TryFormatComment = (offset, instruction, destination, out int written) => { var access = instruction.StatusFlags; if (!access.ReadsAny && !access.WritesAny) { written = 0; return false; } return destination.TryWrite($"reads: {access.Read}; writes: {access.Written}", out written); }; ``` -------------------------------- ### Decode an ARM64 instruction Source: https://github.com/xoofx/asmarm64/blob/main/doc/readme.md Use Decode to obtain an Arm64Instruction object containing full details about the instruction. Note that the library expects little-endian byte order. ```csharp var instruction = Arm64Instruction.Decode(0x5AC02000U); // Prints "abs w0, w0" Console.WriteLine(instruction.ToString()); ``` -------------------------------- ### Arm64Disassembler.Disassemble Source: https://github.com/xoofx/asmarm64/blob/main/doc/readme.md Disassembles a sequence of instructions from a byte buffer. ```APIDOC ## Arm64Disassembler.Disassemble(byte[] buffer) ### Description Disassembles a sequence of instructions provided in a byte buffer and returns the formatted assembly text. ### Parameters - **buffer** (byte[]/Span/ReadOnlySpan) - Required - The buffer containing the instruction sequence. ``` -------------------------------- ### ARM64 Assembly Loop Implementation Source: https://github.com/xoofx/asmarm64/blob/main/src/AsmArm64.Tests/Verified/TestAssembler.TestDisassemblerCustomLabels.verified.txt This code defines a loop that calculates a sum based on a register value. ```asm _start: mov x0, #5 bl sum_loop ret sum_loop: mov x1, #0 mov x2, #0 loop_start: add x1, x1, x2 add x2, x2, #1 cmp x2, x0 b.lt loop_start mov x0, x1 ret ``` -------------------------------- ### Encoding extend operations Source: https://github.com/xoofx/asmarm64/blob/main/doc/readme.md Syntax for applying extend modifiers to instructions. ```c# Arm64InstructionFactory.ADD(SP, X18, X3, _SXTX, 1); // ADD SP, X18, X3, SXTX #1 ``` -------------------------------- ### ARM64 Assembly Code Verification Source: https://github.com/xoofx/asmarm64/blob/main/src/AsmArm64.Tests/Verified/TestAssembler.TestDisassemblerSimple.verified.txt Assembly code snippet used to verify the disassembler's output for basic arithmetic and branching logic. ```asm LL_01: mov x0, #5 bl LL_02 ret LL_02: mov x1, #0 mov x2, #0 LL_03: add x1, x1, x2 add x2, x2, #1 cmp x2, x0 b.lt LL_03 mov x0, x1 ret ``` -------------------------------- ### Detect an ARM64 instruction ID Source: https://github.com/xoofx/asmarm64/blob/main/doc/readme.md Use DecodeId for a lightweight way to retrieve the unique identifier for an instruction at a specific address. ```csharp var instructionId = Arm64Instruction.DecodeId(0x5AC02000U); // Prints "ABS_32_dp_1src" Console.WriteLine(instructionId); ``` -------------------------------- ### Encoding grouped registers Source: https://github.com/xoofx/asmarm64/blob/main/doc/readme.md Syntax for grouping registers in instructions. ```c# Arm64InstructionFactory.LD1(V0.T_16B.Group2(), _[X2]); // LD1 { V0.16B, V1.16B }, [X2] ``` -------------------------------- ### Inspect instruction operands Source: https://github.com/xoofx/asmarm64/blob/main/doc/readme.md Iterate through the Operands collection of an Arm64Instruction to access specific operand details, such as register information and flags. ```csharp var instruction = Arm64Instruction.Decode(0x5AC02000U); foreach (var operand in instruction.Operands) { if (operand.Kind == Arm64OperandKind.Register) { var registerOperand = (Arm64RegisterOperand)operand; // Prints "w0 - Flags: Write" for the first register // Prints "w0 - Flags: Read" for the 2nd register Console.WriteLine($"{registerOperand} - Flags: {registerOperand.Flags}"); } } ``` -------------------------------- ### Perform Label Arithmetic Source: https://github.com/xoofx/asmarm64/blob/main/doc/readme.md Apply signed addends to labels or calculate byte lengths between bound labels using Evaluate. ```csharp using var asm = new Arm64Assembler(0x1000); asm.B(out var target) .NOP() .Label(target) .B(target + 4) .End(); ``` ```csharp asm.Label(out var start) .NOP() .Label(out var end); long byteLength = (end - start).Evaluate(); ``` -------------------------------- ### Encoding memory operands Source: https://github.com/xoofx/asmarm64/blob/main/doc/readme.md Syntax for memory addressing using the _[...] operator. ```c# Arm64InstructionFactory.LDFADD(H0, H1, _[X3]); .// LDFADD H0, H1, [X3] Arm64InstructionFactory.LDRSB(W0, _[X2, X3, _LSL, 0]); // LDRSB W0, [X2, X3, LSL #0] ``` -------------------------------- ### Encoding register types Source: https://github.com/xoofx/asmarm64/blob/main/doc/readme.md Syntax for encoding specific register types like 8B. ```c# Arm64InstructionFactory.ABS(V0.T_8B, V1.T_8B); // ABS V0.8B, V1.8B ``` -------------------------------- ### Declaring forward labels Source: https://github.com/xoofx/asmarm64/blob/main/doc/migration-2.0.md Forward labels can be declared explicitly or inline on generated label operands. ```csharp asm.CBZ(X0, out var done) .ADD(X0, X0, 1) .Label(done) .RET() .End(); ``` -------------------------------- ### Arm64Instruction.DecodeId Source: https://github.com/xoofx/asmarm64/blob/main/doc/readme.md Decodes the instruction ID for a given instruction byte sequence. ```APIDOC ## Arm64Instruction.DecodeId(uint instructionBytes) ### Description Returns the unique instruction ID for the instruction represented by the provided bytes. ### Parameters - **instructionBytes** (uint) - Required - The 32-bit instruction bytes in little-endian order. ``` -------------------------------- ### Configure Disassembler Invalid Data Handling Source: https://github.com/xoofx/asmarm64/blob/main/doc/readme.md Set InvalidDataMode to control how the disassembler processes input buffers that are not multiples of 4 bytes. ```csharp var disassembler = new Arm64Disassembler { Options = { InvalidDataMode = Arm64InvalidDataMode.EmitBytes } }; Console.WriteLine(disassembler.Disassemble(codeWithTrailingBytes)); ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.