8051 Arithmetic Operations Flags, Incrementing and Decrementing,AND Addition

Introduction

Applications of microcontrollers often involve performing mathematical calculations on data in order to alter program flow and modify program actions. A microcontroller is not designed to be a "number cruncher," as is a general-purpose computer. The domain of the microcontroller is that of controlling events as they change (real-time control). A suffi­cient number of mathematical opcodes must be provided, however, so that calculations associated with the control of simple processes can be done, in real time, as the controlled system operates. When faced with a control problem, the programmer must know whether the 8051 has sufficient capability to expeditiously handle the required data manipulation. If it does not, a higher performance model must be chosen.

The 24 arithmetic opcodes are grouped into the following types:

Mnemonic

Operation

INC destination

Increment destination by 1

 DEC destination

 Decrement destination by 1

ADDI ADDC destination ,source

Add source to destination without/with carry (C) flag

SUBB destination.source

Subtract, with carry, source from destination

MUL   AB

 Multiply the contents of registers A and B

DIV AB

Divide the contents of register A by the contents of register B

DA A

Decimal Adjust the A register

The addressing modes for the destination and source are the same as those discussed in Chapter 3: immediate, register, direct, and indirect.

Flags

A key part of performing arithmetic operations is the ability to store certain results of those operations that affect the way in which the program operates. For example, adding together two one-byte numbers results in a one-byte partial sum, because the 8051 is and eight-bit machine. But it is possible to get a 9-bit result when adding two 8-bit numbers. The ninth bit must be stored also, so the need for a one-bit register, or carry Hag in this case, is identified. The program will then have to deal with the ninth bit, perhaps by adding it to a higher order byte in a multiple-byte addition scheme. Similar actions may have to be taken when a larger byte is subtracted from a smaller one. In this case, a borrow is necessary and must be dealt with by the program.

The 8051 has several dedicated latches, or Hags, that store results of arithmetic opera­tions. Opcodes covered in Chapter 6 are available to alter program flow based upon the state of the Hags. Not all instructions change the Hags. but many a programming error has been made by a forgetful programmer who overlooked an instruction that does change a Hag.

The 8051 has four arithmetic Hags: the carry (C), auxiliary carry (AC), overflow (OV), and parity (P).

Instructions Affecting Flags

The C. AC, and OV Hags are arithmetic Hags. They are set to I or cleared to 0 automat­ically, depending upon the outcomes of the following instructions. The following instruc­tion set includes all instructions that modify the flags and is not confined to arithmetic instructions:

INSTRUCTION MNEMONIC

FLAGS AFFECTED

ADD

C       AC         ov

ADDC

C      AC         ov

ANL C,direct

C

CJNE

C

CLR C

C=0

CPL C

C=C

DA A

C

DIV

C=O     OV

MOV C,direct

C

MUL

C=O     OV

ORL C,direct

C

RLC

C

RRC

C

SETB C

C = 1

SUBB

C         AC       OV

One should remember, however, that the flags are all stored in the PSW. Any instruc­tion that can modify a bit or a byte in that register (MOV. SETB, XCH, etc.) changes the Hags. This type of change takes conscious effort on the part of the programmer.


A Hag may be used for more than one type of result. For example, the C flag indicates a carry out of the lower byte position during addition and indicates a borrow during sub­traction. The instruction that last affects a flag determines the use of that flag.

The parity flag is affected by every instruction executed. The P flag will be set to a I if the number of I’s in the A register is odd and will be set to 0 if the number of I’s is even. All O’s in A yield a I’s count of 0, which is considered to be even. Parity check is an elementary error-checking method and is particularly valuable when checking data re­ceived via the serial port.

Incrementing and Decrementing

The simplest arithmetic operations involve adding or subtracting a binary I and a number. These simple operations become very powerful when coupled with the ability to repeat the operation-that is, to "INCrement" or "OECrement" -until a desired result is reached.’ Register, Direct, and Indirect addresses may be INCremented or DECremented. No math flags (C, AC, OV) are affected.

The following table lists the increment and decrement mnemonics.

Mnemonic

Operation

 INC A

Add a one to the A register

INC Rr

 Add a one to register Rr

INC add

Add a one to the direct address

INC@Rp

Add a one to the contents of the address in Rp

INC DPTR

 Add a one to the lti-bit DPTR

DEC A

Subtract a one from register A

DECRr

Subtract a one from register Rr

DEC add

Subtract a one from the contents of the direct address

DEC@Rp

Subtract a one from the contents of the address in register Rp

Note that increment and decrement instructions that operate on a port direct address alter the latch for that port.

The following table shows examples of increment and decrement arithmetic operations:

Mnemonic

Operation

 MOV A,#3Ah

A= 3Ah

 DEC A

 A= 39h

MOV R0,#15h

 R0= 15h

 MOV 15h,#12h

Internal RAM address 15h = 12h

INC@RO

 Internal RAM address 15h = 13h

DEC I5h

Internal RAM address 15h = 12h

INC RO

R0= 16h

MOV 16h,A

Internal RAM address 16h = 39h

INC@RO

Internal RAM address 16h = 3Ah

MOV DPTR,#12

 DPTR = 12FFh

FFh INC DPTR

DPTR = 1300h

DEC 83h

DPTR = 1200h (SFR 83h is the DPH byte)

 

CAUTION

Remember: No math flags are affected.

All 8-bit address contents overflow from Ffh to 00h.

DPTR is 16 bits; DPTR overflows from FFFFh to 0000h.

The 8-bit address contents underflow from 00h to FFh.

 There is no DEC DPTR to match the INC DPTR.

Addition

All addition is done with the A register as the destination of the result. All addressing modes may be used for the source: an immediate number, a register, a direct address, and an indirect address. Some instructions include the carry flag as an additional source of a single bit that is included in the operation at the least significant bit position.

The following table lists the addition mnemonics.

Mnemonic

Operation

ADD A.#n

Add A and the immediate number n; put the sum in A

ADD A,Rr

Add A and register Rr; put the sum in A

 ADD A,add

Add A and the address contents; put the sum in A

ADD A,@Rp

Add A and the contents of the address in Rp; put the sum in A

 

Note that the C flag is set to I if there is a carry out of bit position 7; it is cleared to 0 otherwise. The AC flag is set to 1 if there is a carry out of bit position 3; it is cleared otherwise. The OV flag is set to I if there is a carry out of bit position 7, but not bit position 6 or if there is a carry out of bit position 6 but not bit position 7, which may be expressed as the logical operation

OV = C7 XOR C6

Unsigned and Signed Addition

The programmer may decide that the numbers used in the program are to be unsigned numbers-that is, numbers that are 8-bit positive binary numbers ranging from 00h to FFh. Alternatively, the programmer may need to use both positive and negative signed numbers.

Signed numbers use bit 7 as a sign bit in the most significant byte (MSB) of the group of bytes chosen by the programmer to. represent the largest number to be needed by the program. Bits 0 to 6 of the MSB, and any other bytes, express the magnitude of the num­ber. Signed numbers use a I in bit position 7 of the MSB as a negative sign and a 0 as a positive sign. Further, all negative numbers are not in true form, but are in 2’s comple­ment form. When doing signed arithmetic. the programmer must know how large the largest number is to be-that is, how many bytes are needed for each number.

In signed form, a single byte number may range in size from 10000000b, which is – I 28d to 01111111 b, which is +I 27d. The number 00000000b is 000d and has a posi­tive sign, so there are 128d negative numbers and 128d positive numbers. The C and OV flags have been included in the 8051 to enable the programmer to use either numbering scheme.

Adding or subtracting unsigned numbers may generate a carry flag when the sum ex­ceeds FFh or a borrow flag when the minuend is less than the subtrahend. The OV flag is not used for unsigned addition and subtraction. Adding or subtracting signed numbers can

lead to carries and borrows in a similar manner, and to overflow conditions due to the actions of the sign bits.

Unsigned Addition

Unsigned numbers make use of the carry flag to detect when the result of an ADD opera­tion is a number larger than Ffb. If the carry is set to one after an ADD, then the carry can be added to a higher order byte so that the sum is not lost. For instance,

95d = 0101111 lb

189d = 10111101b

284d 1 000111 00b = 284d

The C flag is set to I to account for the carry out from the sum. The program could add the carry flag to another byte that forms the second byte of a larger number.

Signed Addition

Signed numbers may be added two ways: addition of like signed numbers and addition of unlike signed numbers. If unlike signed numbers are added, then it is not possible for the result to be larger than -128d or + 127d, and the sign of the result will always be correct. For example,

-001d 11111111b

+027d = 0001 1011b

+026d    0001 1010b = +026d

Here, there is a carry from bit 7 so the carry flag is I. There is also a carry from bit 6, and the OV flag is 0. For this condition, no action need be taken by the program to correct the sum.

If positive numbers are added, there is the possibility that the sum will exceed +I 27d, as demonstrated in the following example:

+ 100d = 01100100b

+050d = 001 10010b

+ 150d 10010110b = -106d

Ignoring the sign of the result, the magnitude is seen to be +22d which would be correct if we had some way of accounting for the + 128d, which, unfortunately, is larger than a single byte can hold. There is no carry from bit 7 and the carry flag is O; there is a carry from bit 6 so the OV flag is 1.

An example of adding two positive numbers that do not exceed the positive limit is:

+045d 00101101b

+075d = 01001011lb

+120d 01111000b = 120d

Note that there are no carries from bits 6 or 7 of the sum; the carry and OV flags are both 0.

The result of adding two negative numbers together for a sum that does not exceed the negative limit is shown in this example:

-030d = 11100010b

-050d = 11001110b

-080d  10110000b = -080d


Here, there is a carry from bit 7 and the carry flag is I; there is a carry from bit 6 and the OV flag is 0. These are the same flags as the case for adding unlike numbers; no correc­tions are needed for the sum.

When adding two negative numbers whose sum does exceed – l 28d, we have

-070d = 10111010b

-070d = 10111010b

-140d 01110100b = +116d

Or, the magnitude can be interpreted as – l 2d, which is the remainder after a carry out of – l 28d. In this example, there is a carry from bit position 7, and no carry from bit position 6, so the carry and the OV flags are set to I. The magnitude of the sum is correct; the sign bit must be changed to a I.

From these examples the programming actions needed for the C and OV flags are as follows:

FLAGS

ACTION

C

OV

0

0

None

0

1

Complement the sign

1

0

 None

1

1

Complement the sign

A general rule is that if the OV flag is set, then complement the sign. The OV flag also signals that the sum exceeds the largest positive or negative numbers thought to be needed in the program.

Multiple-Byte Signed Arithmetic

The nature of multiple-byte arithmetic for signed and unsigned numbers is distinctly different from single byte arithmetic. Using more than one byte in unsigned arithmetic means that carries or borrows are propagated from low-order to high-order bytes by the simple technique of adding the carry to the next highest byte for addition and subtracting the borrow from the next highest byte for subtraction.

Signed numbers appear to behave like unsigned numbers until the last byte is reached.

Foi a signed number, the seventh bit of the highest byte is the sign; if the sign is negative, then the entire number is in 2’s complement form.

For example, using a two-byte signed number, we have the following examples:clip_image002[4]

Note that the lowest byte of the numbers 00000 and – 32768d are exactly alike, as are the lowest bytes for+ 32767d and -00001d.

For multi-byte signed number arithmetic, then, the lower bytes are treated as un­signed numbers. All checks for overflow are done only for the highest order byte that contains the sign. An overflow at the highest order byte is not usually recoverable. The programmer has made a mistake and probably has made no provisions for a number larger than planned. Some error acknowledgment procedure, or user notification, should be in­cluded in the program if this type of mistake is a possibility.


The preceding examples show the need to add the carry Hag to higher order bytes in signed and unsigned addition operations. Opcodes that accomplish this task are similar to the ADD mnemonics: A C is appended to show that the carry bit is added to the sum in bit position 0.

The following table lists the add with carry mnemonics:

Mnemonic

Operation

ADDC A,#n

Add the contents of A, the immediate number n, and the C Hag; put the sum in A

ADDC A,add

Add the contents of A, the direct address contents, and the C Hag; put the sum in A

ADDC A,Rr A

Add the contents of A, register Rr, and the C Hag; put the sum in A

DDC A,@Rp

Add the contents of A, the contents of the indirect address in Rp, and the C flag; put the sum in A

Note that the C, AC, and OY flags behave exactly as they do for the ADD commands.

The following table shows examples of ADD and ADDC multiple-byte signed arith­metic operations:

Mnemonic

Operation

MOV A,#1Ch

A= 1Ch

MOV R5,#0Alh

 R5 = A1h

ADD A,R5

A = BDh; C = 0, OV = 0

ADD A,R5

A = 5Eh; C = 1, OV = 1

ADDC A,#10h

A = 6Fh; C = 0, OV = 0

ADDC A,#IOh

A = 7Fh; C = 0, OV = 0

CAUTION

ADDC is normally used to add a carry after the LSB addition in a multi-byte process. ADD is normally used for the LSB addition.

Leave a comment

Your email address will not be published. Required fields are marked *