Fast Non-ANSI Approaches To Checking Data Type Overflow
|< back

A very common situation is where two bytes are to be added together and the result limited to 255, i.e. the maximum byte value. With the 8051 being byte-orientated, incurring integers must be avoided if maximum speed is to be achieved. Likewise, if the sum of two numbers exceeds the type maximum the use of integers is needed.

In this example, the first comparison uses a proper ANSI approach. Here, the two numbers are added byte-wise and any resulting carry used to form the least significant bit of the upper byte of the notional integer result. A normal integer compare then follows. Whilst C51 makes a good job of this, a much faster route is possible, as shown in the second case.

; #include <reg51.h>
; 
; 
; unsigned char x, y, z ;
; 
; /*** Add two bytes together and check if the result has exceeded 255 ***/
; 
; void main(void) {
	RSEG  ?PR?main?T
	USING	0
main:
			; SOURCE LINE # 8
; 
;    if(((unsigned int)x + (unsigned int)y) > 0xff) {
			; SOURCE LINE # 10
	MOV  	A,x
	ADD  	A,y
	MOV  	R7,A
	CLR  	A
	RLC  	A
	MOV  	R6,A
	SETB 	C
	MOV  	A,R7
	SUBB 	A,#0FFH
	MOV  	A,R6
	SUBB 	A,#00H
	JC   	?C0001
; 
;       z = 0xff ;   // ANSI C version
			; SOURCE LINE # 12
	MOV  	z,#0FFH
;       }
			; SOURCE LINE # 13

In this case, the carry flag, “CY”, is checked directly, removing the need to perform any integer operations. As any addition resulting in a value over 255 sets the carry. Of course, this is no longer ANSI C as a reference to the 8051 carry flag has been made.

?C0001:
; 
;    z = x + y ;
			; SOURCE LINE # 15
	MOV  	A,x
	ADD  	A,y
	MOV  	z,A
; 
;    if(CY) {
			; SOURCE LINE # 17
	JNB  	CY,?C0003
;  
;       z = 0xff ;   // C51 Version using the carry flag
			; SOURCE LINE # 19
	MOV  	z,#0FFH
;       }
			; SOURCE LINE # 20
; 
; 
;    
; 
;    }
			; SOURCE LINE # 25
?C0003:
	RET  	

The situation of an integer compare for greater than 65535 (0xffff) is even worse as long maths must be used. This is almost a disaster for code speed as the 8051 has very poor 32 bit performance. The trick of checking the carry flag is still valid as the final addition naturally involves the two upper bytes of the two integers.

In any high performance 8051 system, this loss of portability is acceptable as it allows run time targets to be met.