You are on page 1of 70

Assembly Language of 8051

Pseudo-instructions/ Assembler Directives


Beside mnemonics, directives are used to define variables and memory
locations where the machine codes are stored. These directives are
interpreted by assembler during the conversion of the assembly language
program into machine codes.

- ORG (origin)
indicates the beginning address of source program.
The number that comes after ORG can be either hex or decimal.
Eg. 1. ORG 0250
2. ORG 0100H; tells assembler that source program starts at the
address 100H in the program memory.
- END
indicates to the assembler the end of the source assembly instructions.

EQU (equate): assigns a value to a symbol


used to define a constant without occupying a memory location. It does
not set aside storage for a data item but associates a constant value with a
data label so that when the label appears in the program. Its constant
value will be substituted for the label.
Eg.
COUINT EQU 37
:
:
MOV R0, #COUNT

TEN EQU 10 ;Symbol equated to a number


COUNTER EQU R7 ;User defined symbol for the implicit
;operand symbol R7. COUNTER can now
;be used wherever it is legal to use
;R7. For example the instruction
;INC R7 could now be written INC COUNTER.
ALSO_TEN EQU TEN ;Symbol equated to a previously defined
;symbol.
FIVE EQU TEN/2 ;Symbol equated to an arithmetic exp.

SET directive:
Similar to the EQU directive, the SET directive is used to assign a value
or implicit operand to a user defined symbol. The difference however, is
that with the EQU directive, a symbol can only be defined once.
POINTER SET R0 ;Symbol equated to register 0
POINTER SET R1 ;POINTER redefined to register 1
COUNTER SET 10 ;Symbol initialized to 10

DB (define byte)
used to define 8-bit data and store them in assigned memory locations.
Define data can be in decimal, binary, hex, or ASCII formats. Can be
used to implement lookup table technique.

DATA :
DATEA1 :

DB 42, 35D, 8FH, 00100110B


DB 2012

The BIT Directive assigns an internal bit memory direct address to the
symbol.
CF BIT 0D7H

;The single bit Carry Flag in PSW

OFF_FLAG BIT 6

;Memory address of single bit flag

ON_FLAG BIT OFF_FLAG+1 ;Next bit is another flag

Types of 8051 instructions

1. Data transfer: MOV, MOVC, MOVX, PUSH, POP etc.


2. Arithmetic: ADD, SUBB, MUL, DIV, INC, DEC, DA A etc

3. Logical: ANL, ORL, XRL, RL, RR etc.


4. Branch: JMP, JC, JNC, JZ, JNZ, CJNE, DJNZ etc.
The 8051 has 255 instructions
Every 8-bit opcode from 00 to FF is used except for A5.

Addressing modes are the methods of accessing the data used by the
instructions.
Addressing mode

Example

Remarks

Immediate Addressing

MOV A,#20h

Data is provided as a part of


instruction

Register Addressing

MOV A, R5

Data is provided in the


register

MOV A,30h

Address of the data is


provided in the instruction
(data is obtained directly
from the memory)

ADD A,@R0

Instruction uses register to


hold the address of the data.
(data is obtained indirectly
from the memory)

Direct Addressing

Indirect Addressing

IIndexed addressing

| MOVC A, @A+PC |

Address of data is
obtained by adding offset
to base register

MOV
8-bit data transfer for internal RAM and the SFR.
MOV A, Rn
MOV A, addr
1. addr is of either
MOV A, @Ri
internal RAM or SFR
MOV A, #data
2. Only R0 or R1 to be
MOV Rn, A
used for indirect
MOV Rn, addr
MOV Rn, #data
addressing
MOV addr, A
3. Both source and
MOV addr, Rn
destination can not be
MOV addr, addr
specified indirectly
MOV addr, @Ri
MOV addr, #data
MOV @Ri, A
MOV @Ri, addr
MOV @Ri, #data

MOV
1-bit data transfer involving the CY flag
MOV C, bit
MOV bit, C

Bit in bit addressable register

Eg. MOV P1.2,C

MOV
16-bit data transfer involving the DPTR
MOV DPTR, #data

MOVX
X means the data movement is external to
the 8051
Data transfer between the accumulator and a
byte from external data memory.

MOVX
MOVX
MOVX
MOVX

A, @Ri
A, @DPTR
@Ri, A
@DPTR, A

Access to external data memory can be either 8-bit


address or 16-bit address

MOVC
Move Code Byte
Load the accumulator with a byte from program
memory (internal /external ROM)
use indexed addressing

MOVC
MOVC

A, @A+DPTR
A, @A+PC

For program memory, always 16 bit address is used.

PUSH / POP
Push and Pop a data byte onto the stack.
The data byte is identified by a direct address
from the internal RAM locations.
PUSH
POP

0E0H
40H

PUSH addr
SP SP+1
(M)SP (M)addr

POP addr
(M)addr (M)SP
(SP) (SP)-1

XCH
Exchange accumulator and a byte variable
XCH A, Rn
XCH A, direct
XCH A, @Ri

XCHD
Exchange lower digit of accumulator with the lower
digit of the memory location specified.
XCHD A, @Ri

The lower 4-bits of the accumulator are exchanged


with the lower 4-bits of the internal memory
location identified indirectly by the index register.
The upper 4-bits of each are not modified.

Ex.1 Copy the contents of external data memory location having address
3000h to internal data memory location having address 25h using
indirect addressing.
MOV DPTR, #3000h
MOV R0, #25h
MOVX A,@DPTR
MOV @RO,A
Ex.2 Copy the contents of external program memory location having
address 3025h to internal data memory location having address 25h
MOV DPTR, #3000h
MOV A, #25h
MOV R0, #25h
MOVC A,@A+DPTR
MOV @RO,A

Ex. 3 Exchange the content of internal data memory location 50h and
external data memory location FF00h
MOV DPTR, #0FF00h
MOVX A, @DPTR
MOV R0, 50h
MOV 50H, A
MOV A, R0
MOVX @DPTR, A

; take the address in dptr


; get the content of FF00h in Acc
; save the content of 50h in R0
; move (A) to address 50h
; get content of 50h in A
; move it to 0FF00h

SUBB A,src
#byte / @Rn / Ri / byte

Mnemonics

Operands

Bytes/Cycles

ADD

A, Rn

1/1

ADDC

A, direct

2/1

SUBB

A, @Ri

1/1

A, #data

2/1

INC

1/1

DEC

Rn

1/1

direct

2/1

@Ri

1/1

INC

DPTR

1/2

MUL

AB

1/4

DIV

AB

1/4

DA

1/1

Arithmetic Instructions
ADD
8-bit addition between the accumulator (A) and
a second operand.
The result is always in the accumulator.
The CY flag is set/reset appropriately.

ADDC
8-bit addition between the accumulator, a
second operand and the previous value of the
CY flag.
Useful for 16-bit addition in two steps.
The CY flag is set/reset appropriately.

SUBB
Subtract with Borrow.
Subtract an operand and the previous value of the
borrow (carry) flag from the accumulator.
A A - <operand> - CY.
The result is always saved in the accumulator.
The CY flag is set/reset appropriately.

Example: Add 1E44H to 56CAH

CLR
MOV
ADD
MOV
MOV
ADDC
MOV

C
A, #44H
A, #CAH
R1, A
A, #1EH
A, #56H
R2, A

; Clear the CY flag


; The lower 8-bits of the 1st number
; The lower 8-bits of the 2nd number
; The result 0EH will be in R1. CY = 1.
; The upper 8-bits of the 1st number
; The upper 8-bits of the 2nd number
; The result of the addition is 75H

The overall result: 750EH will be in R2:R1. CY = 0.

DA A

Decimal adjust the accumulator.

Format the accumulator into a proper 2 digit packed


BCD number.
Operates only on the accumulator.
Works only after the ADD instruction.

1. It adds 6 to the lower nibble of A if it is > 9


or if AC=1
2. It adds 6 to upper nibble of A, if it is >9 or if
CY=1

Add 34 to 49 BCD

MOV A, #34H
ADD A, #49H
DA

; Place 1st number in A


; Add the 2nd number.
; A = 7DH
; A = 83H

INC
Increment the operand by one.
The operand can be a register, a direct address, an
indirect address, the data pointer.

DEC
Decrement the operand by one.
The operand can be a register, a direct address, an
indirect address.

MUL AB / DIV AB
Multiply A by B and place result in A:B.
Divide A by B and place result in A:B.

MUL AB
Uses registers A and B as both source and destination registers
Numbers in A and B are multiplied, then put the lower-order byte of
the product in A and the high-order byte in B
The OV flag is set to 1 if the product > FFh
Note that the C flag is 0 at all times
DIV AB
uses registers A and B as both source and destination registers
The number in A is divided by B. The quotient is put in A and the
remainder (if any) is put in B
The OV flag is set to 1 if B has the number 00h (divide-by-zero error)
Note that the C flag is 0 at all times

Multiply 25H by 65H


MOV A,#25H
MOV B,#65H
MUL AB; result is E99H
Result :
B = 0EH and A = 99H

Divide 95 by 10
MOV A,#95
MOV B,#10
DIV AB
Result:
A =09 (quotient) , B=05 (remainder)

Program : Treat R7-R6 and R5-R4 as two register pairs containing 16 bit
numbers. Subtract first from second. Store the result in 20h (lower byte)
and 21h (higher byte).
CLR C
MOV A, R4
SUBB A, R6
MOV 20H, A
MOV A, R5
SUBB A, R7
MOV 21H, A

; clear carry
; get first lower byte
; subtract it with other
; store the result
; get the first higher byte
; subtract from other
; store the higher byte

subtract the lower bytes and then subtract higher bytes

LOGICAL INSTRUCTIONS

There are instructions available for the 8051 to implement the following
logic functions
AND
OR
XOR (exclusive-OR)
NOT (invert/complement)

ANL / ORL
Work on byte sized operands or the CY flag.

ANL A, Rn
ANL A, direct
ANL A, @Ri
ANL A, #data
ANL direct, A
ANL direct, #data

ANL C, bit
ANL C, /bit

XRL
Works on bytes only.

CPL / CLR
Complement / Clear.
Work on the accumulator or a bit.

CLR A
All bits in register A are cleared
CPL A
All bits in register A are complemented (inverted)
CLR P1.2
CPL C
*Note that CLR and CPL instructions operate on register A
or a bit in bit addressable register.

The Rotate Instructions


Contents in register A is rotated one bit position to the left or to the
right (operated in A only).

The bit shifted out is used as the new bit shifted in.
May include the C flag in the operation.

Useful in inspecting the bits in a byte one by one and also useful for
multiplication and division in powers of 2.

RL A
Rotates A one bit position to the left
RLC A
Rotates A and the carry flag one bit position to the left
RR A
Rotates A one bit position to the right

RRC A
Rotates A and the carry flag one bit position to the right
Note that for RLC and RRC, you have to know the C flag first
We can use rotate instructions for data serialization.
Serializing data is a way of sending a byte of data one bit at a time
through a single pin of microcontroller.

Ex. Store the higher nibble of R7 in to both nibbles of R6


MOV A, R7
ANL A, #0F0H
MOV R6, A
SWAP A
ORL A, R6
MOV R6, A

; get the content in acc


; mask lower bit
; send it to r6
; xchange upper and lower nibbles of acc
; OR operation
; finally load content in r6

BRANCHING INSTRUCTIONS

Jumps can

1. be conditional or unconditional
2. be relative or absolute short or absolute long (range of jump)
3. test bit or byte

Jump and Call Instructions


The 8051 provides four different types of unconditional
jump instructions:
Relative Jump SJMP raddr
Uses an 8-bit signed offset relative to the 1st byte of
the next instruction.
Absolute Long Jump LJMP laddr
Uses a 16-bit address.
3 byte instruction capable of referencing any
location in the entire 64K of program memory.

Absolute short Jump AJMP saddr


Uses an 11-bit address.
2 byte instruction
The upper 3-bits of the address combine with the 5-bit opcode to
form the 1st byte and the lower 8-bits of the address form the 2nd
byte.

The 11-bit address is substituted for the lower 11-bits of the


PC to calculate the 16-bit address of the target.
The location referenced must be within the 2K Byte memory page
containing the AJMP instruction.
if the AJMP command is at code memory location 650h, it can only
do a jump to addresses 0000h through 07FFh

Indirect Jump JMP 16bit-addr


JMP @A + DPTR

Infinite Loops

Start: mov C, p3.7


mov p1.6, C
sjmp Start
Microcontroller application programs are almost always infinite loops!

The 8051 supports 5 different conditional


jump instructions.
ALL conditional jump instructions use an 8-bit
signed offset.
Jump on Zero JZ / JNZ raddr
Jump relative if the A == 0 / A != 0
Byte Testing (there is no zero flag)

Jump on Carry JC / JNC raddr


Jump relative if the C flag is set / cleared.
Bit testing

Jump on Bit
JB / JNB b, raddr
Jump if the specified bit is set / cleared.
Any addressable bit can be specified.

Jump if the Bit is set then Clear the bit


JBC b, raddr
Jump if the specified bit is set.
Then clear the bit.

Compare and Jump if Not Equal CJNE


Compare the magnitude of the two operands
and jump if they are not equal.
The values are considered to be unsigned.
The Carry flag is set / cleared appropriately.

CJNE A, addr, raddr


CJNE A, #data, raddr
CJNE Rn, #data, raddr
CJNE @Ri, #data, raddr

if (A) (M)addr then jump to the relative address

if (A) < (M)addr then jump to the relative address & CY is set

if (A) > (M)addr then jump to the relative address & CY is reset

Decrement and Jump if Not Zero DJNZ


Decrement the first operand by 1 and jump to
the location identified by the second operand if
the resulting value is not zero.
DJNZ Rn, raddr
DJNZ direct, raddr

No Operation
NOP

Subroutines
call to the subroutine

Main:

...
acall sublabel
...
...
sublabel:...
the subroutine
...
ret

Why Subroutines?
Subroutines allow us to have "structured"
assembly language programs.
This is useful for breaking a large design
into manageable parts.
It saves code space when subroutines can be
called many times in the same program.

The 8051 provides 2 forms for the CALL


instruction:
Absolute short Call ACALL saddr
Uses an 11-bit address similar to AJMP
The subroutine must be within the same 2K page.

Absolute Long Call LCALL laddr


Uses a 16-bit address similar to LJMP
The subroutine can be anywhere.

Both forms push the 16-bit address of the next


instruction on the stack and update the stack
pointer.

The 8051 provides 2 forms for the return


instruction:
Return from subroutine RET
Pop the return address (top 2 bytes) from the stack
into PC, decrement the SP by 2 and continue
execution at this new address.
Used to return from subroutine previously entered
by instructions LCALL or ACALL.

Return from ISR RETI


Pop the return address (top 2 bytes) from the stack into PC,
decrement SP by 2 and continue execution at the new address
retrieved from the stack.
This is used to return from ISR or interrupt handler.
Restore the interrupt logic to accept additional interrupts at the
same priority level as the one just processed.
The PSW is not automatically restored.

Lookup table technique


Program to fetch a square of a number between 0 to 9 from the table:
MOV A,R3
INC A
MOVC A,@A+PC
RET
SQR: DB 0,1,4,9,16,25,36,49,64,81

1. PC is incremented to address of next instruction RET, before it is


added to the A to form the address of the desired data.
2. INC A is needed bypass the single byte of opcode belonging to RET
instruction.

ORG 100H
MOV DPTR,#200H
MOV A,R3
MOVC A,@A+DPTR
RET
ORG 200H
SQR: DB 0,1,4,16,25,36,49,64,81
END

MOVC A,@A+PC may be preferable over MOVC A,@A+DPTR, if we


do not want to divide the program code space into two separate areas of
code and data. As a result, we do not waste valuable on chip code space
located between the last byte of program and beginning of the data space
where the look up table is located.

Machine cycles
The oscillator formed by the crystal and associated circuit generates a
pulse train at the crystal frequency fosc.
The minimum time required by the microcontroller to complete a
simple instruction, or part of a more complex instruction, is the machine
cycle.
The machine cycle consists of a sequence of six states, numbered S1
through to S6, with each state time lasting for two oscillator periods.
Thus a machine cycle takes 12 oscillator periods.

Normally two program fetches are generated during each machine


cycle even if the instruction being fetched does not require it. If the
instruction being executed does not need extra code bytes the CPU
ignores the extra fetch and the PC is not incremented.

Execution of a one-cycle instruction begins during S1 of the machine


cycle with the opcode latched into the instruction register. A second fetch
occurs during S4 of the same machine cycle and execution is completed
at the end of S6 of the machine cycle.
The MOVX instructions take two machine cycles to complete and no
program fetch is generated during the second machine cycle of the
instruction. This is the only time that program fetches are skipped.

Instruction Time Calculation


Depends on the clock frequency of oscillator
1 machine cycle = 12 oscillator cycle
For a 11.0592MHz oscillator, the time for 1machine cycle is:

Find the execution time for the following program segment,


assuming a crystal frequency of 11.0592MHz.

1
1
4
2
1
2
1
1
1

Total machine cycles required,


[1 + 1 + 4 + 1 + 2 + 1 + 1 + 2 + 1 ] = 14 machine cycles
The execution time of the program segment is :
Execution time = 14 x 1.085s

The crystal frequency is given as 12 MHz. Make a subroutine that will


generate delay of exact 1 ms. Use this delay to generate square wave of
50 Hz on pin P2.0
LOOP: SETB P2.0
; send 1 to port pin
MOV R6, #0AH
; load 10d in r6
ACALL DELAY
; call 1 ms delay 10 = 10 ms
CLR P2.0
; send 0 to port pin
MOV R6, #0AH
; reload 10d in r6
ACALL DELAY
; call 1 ms delay 10 = 10 ms
SJMP LOOP
; continuous loop
Delay:
; load count 250d
LP2:
MOV R7, #0FAH
LP1:
NOP
; 1 cycle
NOP
; 1 cycle
DJNZ R7, LP1
; 2 cycles
DJNZ R6, LP2
; 4250 = 1000 cycles = 1000 s = 1 ms
RET
50 Hz = 20 ms. square wave will have 10 ms ontime and 10 ms offtime. Send 1 for 10
ms to port pin and for another 10 ms send 0 in continuous loop.

Serializing data is a way of sending or receiving a byte of data one bit at


a time through a single pin of microcontroller.
A program to transfer a value 52H serially (LSB first) via pin P1.3. Put
one high and one low at the start and end of data.

Nextbit:

MOV A,#52H
SETB P1.3
CLR P1.3
MOV R0,#8 ;counter
RRC A
MOV P1.3,C
DJNZ R0,nextbit
SETB P1.3
CLR P1.3

1)Transfer the block of data from 20h to 30h to external location 1020h
to 1030h.

nxt:

MOV R7, #11H


; initialize counter by 17d
MOV R0, #20H
; get initial source location
MOV DPTR, #1020H ; get initial destination location
MOV A, @R0
; get first content in acc
MOVX @DPTR, A ; move it to external location
INC R0
; increment source location
INC DPTR
; increase destination location
DJNZ R7, nxt
; decrease r7. if zero then over
otherwise move next

To transfer 10 data bytes from internal to external RAM, we need one


counter and two pointers: one for source and second for destination.

2)Find out how many corresponding equal bytes between two memory
blocks 10h to 20h and 20h to 30h.
MOV R7, #11H
; initialize counter by 17d
MOV R0, #10H
; get initial location of block1
MOV R1, #20H
; get initial location of block2
MOV R6, #00H
; equal byte counter. Starts from zero
NXT: MOV A, @R0
; get content of block 1 in acc
MOV B, A
; move it to B
MOV A, @R1
; get content of block 2 in acc
CJNE A, B, NOMATCH ; compare both if equal
INC R6
; increment the counter
NOMATCH:
INC R0
; otherwise go for second number
INC R1
DJNZ R7, NXT ; decrease r7. if zero then over otherwise move next

Compare each byte one by one from both blocks. Increase the count
every time when equal bytes are found

3) Given block of 255 bytes starting from 100h. Find out how many
bytes from this block are greater than the number in r2 and less then
number in r3. Store the count in r4.
MOV DPTR, #0100H
MOV R7, #0FFH
MOV R4, #00H
MOV 20H, R2
MOV 21H, R3
NXT: MOVX A, @DPTR
CJNE A, 21H, LOWER
SJMP OUT
LOWER: JNC OUT
CJNE A, 20H, LIMIT
SJMP OUT
LIMIT: JC OUT
INC R4
OUT: INC DPTR
DJNZ R7, NXT

; get initial location


; counter
; number counter
; get the upper and lower limits in
; 20h and 21h
; get the content in acc
; check the upper limit first
; if number is larger
; jump out
; check lower limit
; if number is lower
; jump out
; if number within limit increment count
; get next location
; repeat until block completes

take each byte one by one from given block. two limits are given: higher limit in r3 and
lower limit in r2. check first higher limit and then lower limit if the byte is in between these
limits then increment the count.

You might also like