Provided by: radare2_6.0.7+ds-1_amd64 bug

NAME

       r_asm — Assembler and disassembler library for radare2

SYNOPSIS

       #include <r_asm.h>

DESCRIPTION

       The  r_asm  API  exposes  radare2's high level assembler and disassembler primitives and the glue between
       them.

       It is implemented as a frontend for the r_arch api that provides the architecture  logic  to  encode  and
       decode  instructions.  But  offers  support  for  multiline  assembler with directive handling and pseudo
       disassembling and parsing plugins.  Routines  operate  on  the  RAsm  context  which  holds  architecture
       configuration,  current  program  counter  and parser state. Results for multi-instruction operations are
       returned in RAsmCode objects which contain raw bytes, the disassembly text and per-assembly metadata.

INITIALIZATION

       Before assembling or disassembling you must create and configure an RAsm r2  RAsm  r_asm_set_user_ptr(())
       RCore
        helpers (like address-size prediction) work correctly..Pp

             /* Initialization API (prototypes) */
             RParse *r_parse_new (void);
             void r_parse_free (RParse *p);

             RAsm *r_asm_new (void);
             void r_asm_free (RAsm *a);
             void r_asm_set_user_ptr (RAsm *a, void *user);
             bool r_asm_use (RAsm *a, const char *name);
             int r_asm_set_bits (RAsm *a, int bits);
             int r_asm_set_pc (RAsm *a, ut64 pc);
       Example initialization and cleanup:

             RAsm *a = r_asm_new();
             /* choose architecture and word size */
             r_asm_use (a, "x86");
             r_asm_set_bits (a, 64);
             /* set current location for relative operands and disassembly helpers */
             r_asm_set_pc (a, 0x1000);
             /* when embedding in r2: r_asm_set_user_ptr (a, core); */

             r_asm_free (a);

ASSEMBLY

       The  assembler  API  provides  two levels of convenience. Use r_asm_assemble(()) when you need multi-line
       assembly, directive handling or want a RAsmCode result with both bytes and the  produced  assembly  text.
       For  single-line or binding-specific assembly callbacks use the lower-level encode callbacks that plugins
       expose.   If  you  only  need  a  raw  buffer  of  bytes  from  a  textual   instruction,   the   utility
       r_asm_from_string(())

             /* Assembly API (prototypes) */
             RAsmCode* r_asm_assemble (RAsm *a, const char *buf);
             ut8 *r_asm_from_string (RAsm *a, ut64 addr, const char *b, int *l);
             void r_asm_code_free (RAsm *acode);
       The  assembler  honors  directives  embedded in the input (such as .bits, .arch, or .endian) and uses the
       configured parser plugin to support pseudo-instructions.

             /* assemble several instructions and inspect bytes */
             RAsmCode *code = r_asm_assemble (a, "mov rax, 420op");
             if (code) {
                 for (int i = 0; i < code->len; i++) {
                     printf ("%02x ", code->bytes[i]);
                 }
                 printf ("%s0, code->assembly);
                 r_asm_code_free (code);
             }

             /* get a plain buffer (useful for embedding into other APIs) */
             int len;
             ut8 *buf = r_asm_from_string (a, 0x1000, "add eax, 1", &len);
             if (buf) { free (buf); }

DISASSEMBLY

       There  are  two   complementary   disassembly   APIs.   The   low-level   r_asm_disassemble(())   RAnalOp
       r_asm_mdisassemble(()) RAsmCode

             /* Disassembly API (prototypes) */
             int r_asm_disassemble (RAsm *a, RAnalOp *op, const ut8 *buf, int len);
             RAsmCode* r_asm_mdisassemble (RAsm *a, const ut8 *buf, int len);
             char *r_asm_tostring (RAsm *a, ut64 addr, const ut8 *b, int l);
             RAsmCode* r_asm_mdisassemble_hexstr (RAsm *a, RParse *p, const char *hexstr);
             void r_asm_op_init (RAnalOp *op);
             void r_asm_op_fini (RAnalOp *op);
       The  typical  decoding loop used in rasm2 and other tools calls r_asm_disassemble(()) repeatedly, updates
       the PC via r_asm_set_pc((),) and finalizes each RAnalOp with r_asm_op_fini(().)

             /* decode a buffer instruction-by-instruction */
             RAnalOp op;
             int off = 0;
             while (off < buflen) {
                 r_asm_op_init (&op);
                 r_asm_set_pc (a, base_addr + off);
                 int sz = r_asm_disassemble (a, &op, buf + off, buflen - off);
                 if (sz <= 0) { break; }
                 printf ("%s0, op.mnemonic);
                 off += op.size;
                 r_asm_op_fini (&op);
             }

       For quick textual conversion of a byte buffer use r_asm_tostring(()) or r_asm_mdisassemble(()) ; to parse
       a hex string and optionally run the pseudo-assembly parser pass use r_asm_mdisassemble_hexstr(().)

PARSING

       The assembler includes a lightweight parse/filter layer  used  to  transform  or  annotate  the  produced
       assembly. The RParse r_asm_use_parser(().)

             /* Parsing API (prototypes) */
             RParse *r_parse_new (void);
             void r_parse_free (RParse *p);
             bool r_asm_use_parser (RAsm *a, const char *name);
             char *r_asm_parse_pseudo (RAsm *a, const char *data);
       Common  usage  patterns  are: run r_asm_mdisassemble_hexstr(()) with an RParse instance to post-process a
       hex string, or call r_asm_parse_pseudo(()) on a previously  decoded  mnemonic  to  get  a  human-friendly
       representation (for example replacing memory operands with symbolic names). Example:

             RParse *p = r_parse_new();
             p->pseudo = true; /* enable pseudo transformations */
             RAsmCode *c = r_asm_mdisassemble_hexstr (a, p, "4868 2a000000");
             if (c) { printf ("%s0, c->assembly); r_asm_code_free (c); }
             r_parse_free (p);

EXAMPLES

       Below  are  short  examples  that  mirror  patterns used across the codebase (see (libr/main/rasm2.c) and
       (libr/core/cmd_print.inc.c) for complete usages).

       Assemble multiple lines and print the encoded bytes:

             RAsmCode *ac = r_asm_assemble (a, ".bits 640ov rax, 420op");
             if (ac) {
                 for (int i = 0; i < ac->len; i++) printf ("%02x", ac->bytes[i]);
                 r_asm_code_free (ac);
             }

       Assemble and analyze instructions producing ESIL (pattern used by the r2 commands that print analysis):

             RAsmCode *acode = r_asm_assemble (a, "mov rax, 420dd rax, 1");
             if (acode) {
                 RAnalOp aop = {0};
                 int printed = 0;
                 while (printed < acode->len) {
                     aop.size = 0;
                     if (r_anal_op (anal, &aop, base_addr, acode->bytes + printed, acode->len - printed,
                                    R_ARCH_OP_MASK_ESIL) > 0) {
                         printf ("%s0, R_STRBUF_SAFEGET (&aop.esil));
                     }
                     printed += aop.size;
                     r_anal_op_fini (&aop);
                 }
                 r_asm_code_free (acode);
             }

       Disassemble a hex string and run the pseudo-parser (as used by the print command):

             RParse *p = r_parse_new();
             p->pseudo = true;
             RAsmCode *c = r_asm_mdisassemble_hexstr (a, p, "4868 2a000000");
             if (c) { puts (c->assembly); r_asm_code_free (c); }
             r_parse_free (p);

SEE ALSO

       r_arch(3), r_anal(3), r_core(3)

Debian                                         September 21, 2025                                       R_ASM(3)