D52 Disassembler User's Manual

8052 Disassembler for Linux and Windows
GNU General Public License
Copyright 2005 by Jeffery L. Post
 theposts <AT> pacbell <DOT> net
Hosted on www.8052.com

Version 3.3.6 - January, 2005

This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA

The file COPYING contains the full text of the GNU General Public License, Version 2.


Back to top


The D52 disassembler allows the user to specify memory areas as code, binary data (8 or 16 bit), ascii text, address tables, or data that should be ignored (not disassembled). You may specify such areas in an ascii text file with the same name as the file to be disassembled, but with an extension of ctl (for example: program.ctl controls the disassembly of program.hex or program.bin).

With the use of a control file, you can, by an iterative process, get a progressively more meaningful disassembly by modifying the control file based on examination of the output of previous runs of the disassembler. You can also specify names for labels and symbols in the control file, resulting in a much more readable source file.

Labels and symbols may have as many characters as will fit in one line of the control file, but some cross assemblers (and especially cross linkers) will truncate any more than some fixed number of characters. Consult your cross development tool documentation. Labels and symbols are not case sensitive.

The control file may exist in either the current directory or the directory of the file to be disassembled. If it is in both directories, the control file in the current directory will take precedence. The output file will always be placed in the current directory.

The getting started section of this document gives some minimal information for users who are eager to try out the disassembler. For best use of the disassembler, however, you should read the sections on command line options and control file directives before proceeding.

Much of the information in this manual also applies to the 8048 and Z80 disassemblers. Invoking these disassemblers without any command line parameters will display a list of options for D48 and DZ80.

D52 is a tool for educational use and for recovering source code that has been lost or is unavailable. Disassembling a program may be unethical or illegal under some circumstances. It is your sole responsibility to determine whether use of D52 for a particular purpose is both legal and ethical.

Back to top

Getting Started

D52 is a command line disassembler. To disassemble a file called 'program.bin' or 'program.hex', type in (at the command line prompt):
d52 -d program
A control file with the same name as the file to be disassembled, but with an extension of '.ctl' can be created in which you can specify areas of memory to be ascii text, 8-bit binary data, 16-bit binary data, etc. A control file is not necessary for disassembly, but as will be seen, it will provide for a much more complete disassembly. The t option will cause D52 to trace and analyze the code before disassembly, and will create a preliminary control file.

If a file extension is not provided and neither the b option nor the h option is specified on the command line, the disassembler will first search for a hex file and, if it is not found, will then search for a bin file. The disassembler can be forced to look for only one or the other by specifying either the binary or the hex option on the command line:
d52 -db program for the file program.bin, or
d52 -dh program for the file program.hex
If a file extension of '.hex' or '.bin' is provided in the filename (ie: d52 test.hex), that is equivalent to using the h option or b option.

D52 will produce a file named 'program.d52' containing the disassembly of the 8051/8052 instructions in the original hex or binary file. It is very useful on the first few disassemblies to use the d option , which adds a comment field to every line. The comment field contains the hexadecimal address of each instruction, the hex data for each byte in the instruction, and the ascii code for each byte of the instruction.
orl a,#42h; 0df644 42DB
This makes it easy to spot areas of ascii text or other nonexecutable code, and you can then modify the control file to tell the disassembler that these areas should be treated as some other kind of data on subsequent disassemblies. Please see the section on control file directives for specific information.

By examining the output file and then modifying the control file based on the information obtained, you can get a progressively better disassembly of your program. Generally, about half a dozen iterations of the disassembly are enough to produce a very readable source file that can then be modified and reassembled.

Back to top

Command Line Options

Command line options modify the operation of the disassembler. They may be specified on the command line using either Unix style options:
d52 -db filename
or DOS style options:
d52 /d /b filename
Options may be entered in a freeform fashion (in any order or format) provided that any options preceding the filename of the program to be disassembled must begin with either a dash (-) or a slash (/). For example:
d52 /db filename -x1000
d52 filename -d b x1000
d52 -d filename bx1000
all mean exactly the same thing and will cause the disassembler to behave in exactly the same way. Exceptions are that the X option , if used, must be the last option given, and if both the A option and the S option are used, the S option must precede the A option.

Note that the file name specified on the command line does not include the .hex or .bin extension.

Command line options in Version 3.3 are:

A Option (ascii macro)

The A option tells the disassembler to change the db/defb pseudo op to the ascii macro (pseudo op 'ascii' instead of 'db' or 'defb') for areas defined as ascii text. This will cause the disassembler to include a macro definition in the disassembly output file that should expand to 'db' for the cross assembler. To use this option, your cross assembler must be able to handle macros, and in particular, D52's macro format. If used in conjunction with the S option , the S option must come first on the command line.

There are some caveats regarding the ascii macro. The intent of this macro is to make ascii text easier to find in the output file. Once you're satisfied with the readability of the output file, you may want to run the disassembler once more without the A option to produce a file compatible with your cross assembler.

Some cross assemblers treat certain characters within a macro as special meta-characters. The Huntsville Microsystems HMA8051, for example, regards the characters '#', '.' and '\' as special within a macro. If these characters occur in ascii text using the ascii macro of D52, the assembler will do strange and not so wonderful things with them. If this happens, just do not use the A option (by default, it is off).

A problem that will be common with all cross assemblers is that the disassembler does not currently treat the single quote (') character differently than it does other characters within ascii text. Since the disassembler delineates ascii text (whether using the A option or not) with the single quote character, its presence in ascii text areas will cause problems. The only solution to this is to manually edit the output file of the disassembler or to define the byte of the single quote as a binary byte in the control file (see the B control file directive ).

B Option (read binary file)

The B option forces the disassembler to read a binary file (extension '.bin') instead of an Intel hex file (extension .hex). If neither the B option nor the H option are specified, the disassembler will first search for a file with an extension of .hex, and if not found, will then search for a binary file with an extension of .bin.

D Option (put data in comment field)

The D option tells the disassembler to include a comment field in each disassembled line. The comment field will contain the hexadecimal address of each instruction, the hex data for each byte in the instruction, and the ascii code for each byte of the instruction. Example:
(opcode/operands) (address)(data)(ascii)
orl a,#42h ; 0df644 42DB
This makes it easy to spot areas of ascii text or other nonexecutable code, and then modify the control file to tell the disassembler that these areas should be treated as some other kind of data on subsequent disassemblies. Please see the section on control file directives for specific information.

H Option (read hexadecimal file)

The H option forces the disassembler to read an Intel hex file (extension '.hex') instead of a binary file (extension '.bin'). If neither the B option nor the H option are specified, the disassembler will first search for a file with an extension of '.hex', and if not found, will then search for a binary file with an extension of '.bin'.

I option (add include for 'sfr52.inc' file)

The I option adds this line to the .d52 disassembly file:

	include	"sfr52.inc"

The file 'sfr52.inc' includes equates for 8052 special function registers and SFR bits that may be needed by some cross assemblers. The sfr52.inc file should be modified to suite your 8052 cross assembler since the equates required will vary from assembler to assembler. For example, one cross assembler I test with requires the equate for 'acc', and yet another cross assembler not only does not require it, but will generate an error if it is present. You may also need to edit the 'include' pseudo-op in the disassembly file if your cross assembler uses some other pseudo-op to include files (or edit the source file 'd52p2.c' and recompile).

It is best to start out with all the equates in sfr52.inc commented out, find out what undefined label errors your cross assembler generates, then uncomment the required equates in sfr52.inc.

This option is incompatible with the K option.

K Option (disassemble for Keil's A51 assembler)

Tells D52 to generate source code compatible with the older Keil A51 assembler.

NOTE: Newer versions of Keil's A51 assembler (tested with version 7.10) have come into compliance with the rest of the world. Do not use this option with newer versions of A51.

S Option (set string pseudo op)

This option tells the disassembler to generate the pseudo ops 'defb' and 'defw' instead of 'db' and 'dw' for those cross assemblers that may require this. Most cross assemblers understand 'db' and 'dw', so these are the defaults for the disassembler. Use this option for cross assemblers that do not recognize 'db' and 'dw'. If used in conjunction with the A option , the S option must precede the A option on the command line.

T Option (trace and analyze code)

This option tells D52 to trace and analyze the 8052 code before disassembling it. D52 will attempt to determine which parts of the code are actually code, and which parts are ascii text, binary data, pointers, etc. While it does a reasonably good job of analyzing the code on most files, no program can do as good a job as a human programmer. A control file with the same name as the hex or bin file, but with an extension of '.ctl', will be created before the actual disassembly is performed. You can then edit the control file to correct any erroneous directives, or to add new directives.

Warning: Using this option will overwrite any control file that may already exist for the code file being disassembled. It is intended to be used on the first disassembly only.

U Option (upper case output)

Causes labels, symbols, mnemonics, etc to be output in upper case, for cross assemblers that may require upper case code. Comments, literal data values, strings, and other output are not affected by this option.

X Option (add hexadecimal offset to addresses)

This option causes the disassembler to add a hexadecimal offset to the address of every location in the code file. This may be useful for disassembling code that was read from the second (or subsequent) rom of a set of roms. For example, suppose that binary data was obtained from a set of 4K byte eproms (call them rom1 and rom2). Then the first file should be disassembled with the command line:
d52 -d rom1
and the second should be disassembled with the X option:
d52 -d rom2 x1000
The two files then can be combined into one and all references within the disassembled code will be to the correct addresses.

Back to top

Control File Directives

Control directives tell the disassembler to treat specified areas of the code to be disassembled as something other than executable code. The user specifies control directives by editing (with any text editor) a control file with the same name as the file to be disassembled, but with a file extension of .ctl (eg: program.ctl to control the disassembly of the file program.hex or program.bin). A generic control file called 'generic.ctl' is provided to get the user started. Copy 'generic.ctl' to 'file.ctl' where 'file' is the name of the binary or Intel hex file to be disassembled, and modify as required based on the output of the disassembler. Then run the disassembler again to get a more readable disassembly of the code.

All directives consist of a character that specifies the type of data, followed by a hexadecimal number specifying the value or range of values of the data. In the case of a label or symbol directive, the hexadecimal number is followed by ascii text defining the label or symbol. See individual directives for examples. All directives must be in the first column of the line. Directives may be complete words, but only the first character is significant, ie:
Label 0 reset and
looney 0 reset
will both generate the label "reset" for address 0. Note that they are not case sensitive.

Everything following a semi-colon (;) is a comment and will be ignored by the disassembler.

Label and symbol directives differ in that a label refers to an address and a symbol refers to any 8 or 16 bit immediate data. Therefore an opcode such as
mov r2,#data
will cause the disassembler to search only the symbol table for a matching value whereas an opcode such as
mov dptr,#data
will cause the disassembler to search the label table first, and if no matching value is found, to then search the symbol table.

Symbols apply only to immediate data. To specify a symbol for an 8052 data memory location, use the R directive , or to force name substitution for an operand at a given address, use the X directive.

Single values are specified by entering just the value; ranges of values are specified by a start and stop address separated by a dash (-), or by a start address and count separated by a plus (+), ie:
t 1000 the data at address 1000H is ascii text.
t 1000-1010 the data from address 1000H to (and including) address 1010H is ascii text.
t 1000+6 ascii text starting at 1000H for 6 bytes.
Directives are processed in the order in which they are read from the control file. Specifying an area as ascii data and then later specifying it as data to be ignored (uninitialized data) will cause that area to not be disassembled at all. Care must be taken in specifying areas in the control file.

A Directive (address data)

Specifies that the address contains a word value corresponding to an address for which a label should be generated. For example, a vector table may be located at address 0x1000 containing four entries. The user can modify the control file by adding the following entry:
a 1000-1007
This will cause the disassembler to generate the following output lines:
dw vec1
dw vec2
dw vec3
dw vec4
assuming that the control file also contains entries for the values found at those addresses to generate the labels vec1 through vec4. The addresses referenced will be flagged so that labels will be generated in the output file at those addresses.

B Directive (byte binary data)

Specifies that the data is to be interpreted as 8 bit binary data. For example:
b 1000-1007
tells the disassembler that the data from address 1000H to 1007H should generate the line:
db 0,1,2,3,4,5,6,7
assuming that the data at address 1000H and up is 00H, 01H, etc.

C Directive (code data)

Forces the disassembler to interpret the data as executable code. This may be necessary because the disassembler skips over strings of 00H or ffH bytes that occur since they are unlikely to be real code. However, sometimes programmers insert several NOPs for timing purposes.

D Directive (define data type (label or symbol))

d address [0 or label] search label table only
d address [1 or symbol] search symbol table only
d address [2 or none] don't search either table
Forces the disassembler to search only the label or symbol table. This allows you to specify a label and a symbol for the same value. For example:
mov dptr,#1234
would normally search only the label table assuming that the data refers to a code address. If the data is really a constant with the same value as a label, then
d 1 address
will force the disassembler to look only in the symbol table for the string that represents the value of the data. The address is the address of the opcode, not the code location of the data operand.

Note that the last parameter can be either a number (0, 1, or 2) or a word (label, symbol, none). If the last parameter is a word, only the first character is checked for L, S, or N, and is not case sensitive.

F Directive (SFR label definition)

Causes reference to an SFR (special function register) to generate a label for the specified SFR address. This is useful for naming SFRs for non-standard members of the 8052 family. For example, suppose that some manufacturer designs a new 8052 variant and decides to use address efH as a new special function register called 'NEWREG'. Then by adding:
f ef newreg
to the control file, D52 will disassemble the opcodes f5 ef as:
mov newreg,a
instead of:
mov 0efh,a
SFR label names are limited to fifteen characters.

I Directive (ignore data)

Tells the disassembler to ignore a range of addresses that may be initialized by the input file. This is useful when the input file is a binary file generated by an eprom programmer that dumps the entire eprom space. The valid data from a 4K eprom might only be, say, 3K in length. By adding
i c00-fff
to the control file, you tell the disassembler to not disassemble the data from address 0c00H to 0fffH.

K Directive (SFR bit definition)

As with the F directive , you can give a name to a new SFR bit. If a new variant of the 8052 family adds a new interrupt, for instance, its enable bit in the IE register might be bit 6. By adding:
k ae newint (ae is the address of IE.6)
you define bit 6 of the interrupt enable register to be 'ie.newint'. Like SFR label names, SFR bit names are limited to fifteen characters.

L Directive (label definition)

Defines a label to the disassembler. Labels are generated in the output disassembly file whenever a reference to the address is found and the label exists in the label table. Suppose that address 0000H contains the code 01 43 (ajmp 0043H). Then the entry
l 43 start
in the control file will cause D52 to disassemble this code as:
ajmp start
rather than:
ajmp X0043
The code beginning at address 43H will then have the label 'start' in the label field rather than the label 'X0043'. See the entry for the S directive for an explanation of the difference between labels and symbols.

M Directive (bit addressable memory label)

Similar to the K directive , the M directive gives a name to a bit addressable memory location. Example:
m 12 bitflag (12h is the bit address of 22h.2)
would cause the bytes d2 12 to be disassembled as
setb bitflag
instead of
setb 22h.2
As with the K directive, names are limited to fifteen characters.

P Directive (patch inline code)

This directive is of dubious value, but has been added for anyone who might find it useful. The P directive is similar to the comment directive except that the user supplied string is patched into the output stream as code, not as a comment. You could, for instance, patch in a macro definition or an include statement. Patching in executable code is not a real good idea.

R Directive (register definition)

This directive specifies a name for an 8052 register. Direct accesses to registers will normally be disassembled as:
mov rb2r5,a
in the case of register 5 of register bank 2. If the user determines that register 5 of bank 2 is being used as a loop counter, for example, he can give it the name loop by adding:
r 15 loop
to the control file, and the above code will be disassembled as:
mov loop,a
The R directive can assign a name to any internal memory location below the SFR address space.

S Directive (symbol definition)

Defines a symbol to the disassembler. Symbols are output to the disassembly file whenever the value is encountered in the input file and the symbol exists in the symbol table. The user can specify a symbol for a value by a line such as:
s 20 space
Code which uses this value, such as:
mov a,#20h
will then be disassembled as:
mov a,#space
Labels and symbols differ in that a label applies to an address, whereas a symbol applies to any 8 or 16 bit immediate data. For code which can only refer to values, such as
mov a,#20h
only the symbol table will be searched for a matching value. For code which could refer to either an address or a value, such as:
mov dptr,#1234h
the label table will be searched first, and only if no matching value is found will the symbol table then be searched. This search behavior can be modified by use of the d directive or the x directive.

T Directive (text [ascii] data)

Forces the data in the range specified to be disassembled as text (ascii data). Thus the code: 48 69 20 74 68 65 72 65 at address 1000H will be disassembled as:
db 'Hi there' or
ascii 'Hi there' (command line option A used)
by putting the line:
t 1000-1007
in the control file. Otherwise it would be interpreted as:
orl a,r0 ; 1000 48 H
xrl a,r1 ; 1001 69 i
jb 2eh.4,X106d ; 1002 20 74 68 th
xrl a,72h ; 1005 65 72 er
xrl a,t3 ; 1007 65 ff e.
which is unlikely to be what was intended by the original programmer. Data specified by this directive is not checked to verify that it really is ascii data--be careful.

W Directive (word binary data)

Specifies that the data is to be interpreted as 16 bit binary data. For example:
w 1000-1007
tells the disassembler that the data from address 1000H to 1007H should generate the lines:
dw 0
dw 1
dw 2
dw 3
assuming that the data at address 1000H and up is 00H, 00H, 00H, 01H, 00H, 02H, etc. This differs from the A (address) directive in that the A directive also causes a reference to be made to the indirect address. In other words, if the data at address 1000H is 1234H, the A directive will cause a label (X1234) to be put in the output file at address 1234H, whereas the W directive will not.

X Directive (specify name for operand data)

Specify a name for an operand at a particular address. This is similar to the S directive except that it applies only to the given address. For example, if the symbol 'CR' is defined as 0dh, every instance of 0dh as an operand will have the symbol 'CR' substituted. It may be, however, that the value 0dh has a different meaning when used as an operand for a particular instruction. The X directive allows you to modify the interpretation of an operand at specific operand locations. Why not then use the X directive exclusively? Because that would force you to place an X directive in the control file for every instance in which that value appeared as an operand. The S directive, defined only once for an operand value, will substitute the symbol text for every occurrence of that operand value unless overridden by the X directive. Note that the address defined in the X directive is the address of the operand, not the address of the instruction. For example:
X 102 loopinit
forces substitution of the text 'loopinit' for the operand located at address 102h. Therefore an instruction that should be interpreted as
mov r0,#loopinit
will not be disassembled as
mov r0,#CR
if the control file contains the above x directive, and also contains an S directive defining 0dh as 'CR', and the value of the operand for the mov instruction happens to also be 0dh.

# Directive (header comment string)

Defines a comment string to be output prior to disassembly at the specified address. For example:

        # 95
        # 95 Start of initialization
        # 95

in the ctl file would cause the output

        ; Start of initialization
                clr  ea           ;0095     c2 af     B/

assuming that the code 'c2 af' was located at address 0x95. Since ASCII strings consume prodigious amounts of memory, it is wise to use this directive sparingly. It is, however, useful for marking blocks of code that have been identified in previous runs of D52.

! Directive (inline comment string)

Defines a comment string to be output after disassembly at the specified address. For example:

        ! 95 Start of initialization

in the ctl file would cause the output

                clr  ea           ;0095     c2 af     B/    ; Start of initialization

for the above example. Note that inline comments are only available for code and word data, and will do nothing if the data at the specified address is defined as data other than code or word data (ascii text, for example).

Back to top

A Note on Symbols, Labels and Names

An example will best explain the difference between labels, symbols, operand names and register names. Labels refer to program code locations, symbols refer to immediate operands, register names and operand names refer to data memory locations.

Given the hex or binary file produced from the follow source code:

org 30h
mainmov a,30h
mov 30h,r0
mov r1,#30h
sjmp main

and this control file:

l 30main; label for code address
x 33thirty; name for operand at address 33h
s 30alsothirty; symbol for immediate operand
r 30counter; name for data memory address (register) at 30h

D52 will produce the following output:

main:mova,counter; 0030 e5 30e0
movthirty,r0; 0032 88 30.0
movr1,#alsothirty; 0034 79 30y0
sjmpmain; 0036 80 f8.x

Note that the label, symbol, register name, and operand name all have the same value: 30h. But the operand name directive ( x directive) in the control file specifies the address of the operand (in this case 33h), and the other three control file directives refer to the value of the operand. The x directive allows you to use a different name for the same value (unlike a symbol), so that, for example, an operand value of 0dh in one place can be disassembled with the name 'CR' and in another place as, say, 'loop_init_count'.

Format of Output File

The output file for D52 (extension '.d52') contains 8052 instructions and pseudo ops in a format that should be acceptable to any 8052 cross assembler. When assembled, the source file should produce an Intel hex file or binary file that is identical to the original. Identical, in this case, means that the code is the same, not that it necessarily has the same format. The number of bytes in each line of the hex file may differ from the original depending on whether the original was produced by an assembler or was read from an eprom. Each output line is in the following format:
The label field will be generated only if the address of the code is referenced by some other code (a call, for instance), or if the user has specified a label for that address in the control file. The comment field is only generated if the user specifies the D option on the command line. Comments begin with a semicolon and are followed by the hexadecimal address of the instruction, the hex value of the byte(s) for the instruction, and finally by the ascii representation of the instruction byte(s). For example:
X004f: orl p3,#0ffh ; 004f 43 b0 ff C0.
label opcode operands comment
Several things should be noted in this example. The label is 'X' followed by the address of the instruction in four hex digits. This type of label is created by the disassembler when some other code references the address. If the user specifies a label name for the address in the control file ('what' for example), the generated code becomes:
what: orl p3,#0ffh ; 004f 43 b0 ff C0.
If the user were to specify the symbol 'ones' for the value 0ffH, the output would then become:
what: orl p3,#ones ; 004f 43 b0 ff C0.
Also note the ascii representation of the instruction bytes. Bit 7 is forced to zero so that ascii with the high bit set can be viewed (b0H in the example becomes 30H, which is ascii '0'). Any code which is not printable ascii (a control code, for example) is output as a period. This is the case for the byte 0ffH above.

The comment field starts at a different position in the output line depending on the type of data in the input file. For normal executable code, the comment field starts in column 32; for hex data it starts at column 49, and for ascii data it starts in column 56. For many programs, this makes for a more readable source file, but if there is a mix of data types in a short range of addresses, this can lead to some strange looking formatting. The user may want to correct this with a text editor in the final disassembly before modification and reassembly.

Back to top


D52 is distributed under the GNU General Public License. See the file COPYING for details. D52 versions 3.1 and higher are a continuation of the earlier disassembler named D51.

D52 allows the user to specify how code should be disassembled via a control file that defines given areas of the code as ascii text, binary data or other types of non-executable code. By an iterative process of disassembly, control file modification, and further disassembly, the user can obtain a very readable source file that can then be modified and re-assembled by a cross assembler. Several public domain cross assemblers are available.

I've encountered several problems when reassembling the output of D52. Almost all are due to the cross assembler not recognizing SFRs of some of the newer or more exotic 8052 variants. The D52 tables include names for all SFRs that I'm aware of as of May 1995 (there are likely some that I'm not aware of). Such errors might be corrected just by defining a symbol for the SFR in the control file (see the F directive ), but this depends on whether your cross assembler will accept it as a valid operand. If all else fails, replace the offending instruction with a 'db' pseudo op and put the mnemonic and operand in a comment. A similar problem is the assembler not being able to handle a bit addressable SFR address; the only solution I see to this is to use a 'db' pseudo op. All other problems I've seen (not many) have been due to disassembling data as code; this is easily corrected by modifying the control file to specify the correct data type.

Many thanks to numerous beta testers who have made invaluable suggestions for improvement and found more bugs than I care to think about. Also thanks to all the users who have, over the years, also made significant contributions to the betterment of D52. Any remaining deficiencies are solely my fault.

Summary of command line options and control file directives

Command line options:

Control file directives:

Back to top

8052 Register Maps

Addresses of 8052 registers:

Addresses of 8052 Special Function Registers:
80 P0 Port 0
81 SP Stack Pointer
82 DPL Data Pointer (low byte)
83 DPH Data Pointer (high byte)
87 PCON Power Control
88 TCON Timer/Counter Control
89 TMOD Timer/Counter Mode
8A TL0 Timer/Counter 0 (low byte)
8B TL1 Timer/Counter 1 (low byte)
8C TH0 Timer/Counter 0 (high byte)
8D TH1 Timer/Counter 1 (high byte)
90 P1 Port 1
98 SCON Serial Port Control
99 SBUF Serial Data Buffer
A0 P2 Port 2
A8 IE Interrupt Enable
B0 P3 Port 3
B8 IP Interrupt Priority
D0 PSW Program Status Word
E0 ACC Accumulator
F0 B B Register

Back to top

Bit Addressable Special Function Registers

AddressSymbolBit nameFunction
80-87 P0.0-7 Port 0
88 IT0 TCON.0 External Interrupt 0 Type Control
89 IE0 TCON.1 External Interrupt 0 Edge Control
8A IT1 TCON.2 External Interrupt 1 Type Control
8B IE1 TCON.3 External Interrupt 1 Edge Control
8C TR0 TCON.4 Timer 0 Run Control
8D TF0 TCON.5 Timer 0 Overflow Flag
8E TR1 TCON.6 Timer 1 Run Control
8F TF1 TCON.7 Timer 1 Overflow Flag
90-97 P1.0-7 Port 1
98 RI SCON.0 Serial Receive Interrupt Flag
99 TI SCON.1 Serial Transmit Interrupt Flag
9A RB8 SCON.2 Serial Receive Bit 8
9B TB8 SCON.3 Serial Transmit Bit 8
9C REN SCON.4 Serial Receive Enable
9D SM2 SCON.5 Serial Port Mode Specifier
9E SM1 SCON.6 Serial Port Mode Specifier
9F SM0 SCON.7 Serial Port Mode Specifier
A0-A7 P2.0-7 Port 2
A8 EX0 IE.0 Enable External Interrupt 0
A9 ET0 IE.1 Enable Timer 0 Interrupt
AA EX1 IE.2 Enable External Interrupt 1
AB ET1 IE.3 Enable Timer 1 Interrupt
AC ES IE.4 Enable Serial Port Interrupt
AF EA IE.7 Enable Interrupts
B0-B7 P3.0-7 Port 3
B8 PX0 IP.0 External Interrupt 0 Priority
B9 PT0 IP.1 Timer 0 Interrupt Priority
BA PX1 IP.2 External Interrupt 1 Priority
BB PT1 IP.3 Timer 1 Interrupt Priority
BC PS IP.4 Serial Port Interrupt Priority
D0 P PSW.0 Parity
D2 OV PSW.2 Overflow Flag
D3 RS0 PSW.3 Register Bank Select Bit 0
D4 RS1 PSW.4 Register Bank Select Bit 1
D5 F0 PSW.5 Flag 0 (general purpose flag)
D6 AC PSW.6 Auxiliary Carry Flag
D7 CY PSW.7 Carry Flag
E0-E7 ACC.0-7 Accumulator Bits
F0-F7 B.0-7 B Register Bits

Back to top

Addresses of Bit Addressable Memory Locations

AddressMemory location
00-0720.0 - 20.7
08-0F21.0 - 21.7
10-1722.0 - 22.7
18-1F23.0 - 23.7
20-2724.0 - 24.7
28-2F25.0 - 25.7
30-3726.0 - 26.7
38-3F27.0 - 27.7
40-4728.0 - 28.7
48-4F29.0 - 29.7
50-572A.0 - 2A.7
58-5F2B.0 - 2B.7
60-672C.0 - 2C.7
68-6F2D.0 - 2D.7
70-772E.0 - 2E.7
78-7F2F.0 - 2F.7

Back to top