Using r2 with 8051


  • Disassembler
  • Assembler
  • Emulation (esil)
  • Basic address space mapping


  • Debugger


  • Full emulation of memory-mapped registers
  • Memory banking for address spaces > 64K
  • Advanced analysis like local variables, function parameters ..
  • More predefined CPU models

r2 configuration

Set architecture to 8051:

$ r2 -a 8051

Set cpu to desired model:

e asm.cpu = ?

After changing the cpu model, run 'aei' to initialize/reset the registers and mapped memory. For example:

e asm.cpu = 8051-generic

Address spaces and memory mapping

Pseudo-registers are used to control how r2 emulates the multiple address spaces of the 8051. The registers hold the base address where the 8051 memory area is located in r2 address space.

registeraddress spacecomment
_codeCODEProgram memory. Typically located at 0.
_idataIDATA256 bytes of internal RAM.
_sfrSFR128 bytes for special function registers. _sfr is the base address. Registers start at _sfr+0x80.
_xdataXDATA64K of external RAM.
_pdataPDATA, XREGMSB of address of 256-byte page in XDATA accessed with 'movx @Ri' op codes.

The registers are initialized based on the selected CPU. See command 'e asm.cpu=?'.

The registers can be viewed and modified with the 'ar' command. When modifying the pseudo-registers or updating 'asm.cpu', memory will be (re)allocated automatically when the analyzer is invoked the next time (e.g. during 'aei'). Use the 'om' command to see the list of allocated memory blocks.

[0x00000000]> e asm.cpu=8051.generic
[0x00000000]> aei
[0x00000000]> om
 4 fd: 6 +0x00000000 0x00000000 - 0x0000ffff -rwx
 3 fd: 5 +0x00000000 0x20000000 - 0x2000ffff -rw- xdata
 2 fd: 4 +0x00000000 0x10000180 - 0x100001ff -rw- sfr
 1 fd: 3 +0x00000000 0x10000000 - 0x100000ff -rw- idata

Analysis and emulation rely on the address mapping. Setup the pseudo-registers before running analysis, or rerun analysis after updating pseudo-registers.

Address spaces can overlap in r2 memory. This allows emulating 8051 variants that mirror IDATA and SFR into XDATA, or have shared XDATA and CODE address spaces.

For example, the CC2430 from Texas Instruments maps SFR to 0xDF80 and IDATA to 0xFF00 in XDATA memory space. In r2 this can be setup with:

ar _sfr = _xdata + 0xdf00
ar _idata = _xdata + 0xff00

For overlapping areas, r2 will prioritize smaller memory blocks over larger ones. For example, if IDATA is mapped into XDATA, all r2 operations will use IDATA in the overlapping addresses. If you want to use XDATA instead, you can delete the offending map with the command 'om-'. See 'om?'for more information.

For using emulation with overlapping code and RAM spaces, the r2 memory holding the firmware must allow write access. This is best achieved with the command 'omf 4 rwx', with 4 being the id of the firmware file's IO map entry. See 'om?' for more information.

Some 8051 variants use memory banking to address memory spaces larger than 64K. Currently, memory banking is not supported by r2.

Tips & tricks

Use pseudo-registers in r2 commands to calculate addresses. For example:

Hex dump of all special function registers:

px @ _sfr

Write a value to a location in external RAM

wx deadbeef @ _xdata + 0x1234

Set a flag for a variable stored at 0x20 in internal RAM:

f sym.secret @ _idata + 0x20

Adding support for new 8051 variants

Follow these steps to add support for new 8051 variants to r2.

  1. Clone latest version of radare2
  2. In '/libr/anal/p/anal_8051.c' add a new entry to array 'cpu_models[]' to define a name and a memory mapping. The name of the last entry in array must be NULL
  3. In 'libr/asm/p/asm_8051.c' append entry with the same name to '.cpus' attribute
  4. Compile, test your addition, and submit a pull request