Provided by: radare2_6.0.4+dfsg-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_massemble(()) 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 r_asm_rasm_assemble(()) or 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_massemble (RAsm *a, const char *buf);
             RAsmCode* r_asm_rasm_assemble (RAsm *a, const char *buf, bool use_spp);
             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_massemble (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_massemble (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_massemble (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)