unsigned long ul1=XX, ul2=YY, ul; unsigned int ui1=AA, ui2=BB, ui; ui=ui1+ui2; ul=ul1+(ul2+(unsigned long)CY);
I agree; if the size and speed are really important, you'll want an assembler routine to deal with 48-bit integers. From the example code, I'm not sure exactly what you're trying to accomplish, other than adding two 48-bit integers. You have access to the carry bit in the program status word register. How about something along the lines of (warning, code off the top of my head!):
sbit carry = PSW^7; void U48AddEq (U8 data * dst, U8 data * src, U8 len) { bit c = 0; while (len--) { dst[len] += (U8)carry + src[len]; c = carry; } }
; FUNCTION _U48AddEq (BEGIN) ; SOURCE LINE # 73 ;---- Variable 'dst' assigned to Register 'R7' ---- ;---- Variable 'len' assigned to Register 'R3' ---- ;---- Variable 'src' assigned to Register 'R5' ---- ; SOURCE LINE # 74 ; SOURCE LINE # 75 R CLR c ?C0002: ; SOURCE LINE # 77 MOV R6,AR3 DEC R3 MOV A,R6 R xJZ ?C0004 ; SOURCE LINE # 78 ; SOURCE LINE # 79 MOV A,R5 ADD A,R3 MOV R0,A MOV A,@R0 MOV R6,A CLR A RLC A ADD A,R6 MOV R6,A MOV A,R7 ADD A,R3 MOV R0,A MOV A,R6 ADD A,@R0 MOV @R0,A ; SOURCE LINE # 80 R MOV c,C ; SOURCE LINE # 81 R xJMP ?C0002 ; SOURCE LINE # 82 C51 COMPILER V7.02b MAIN 03/04/2003 13:39:31 PAGE 4 ?C0004: RET
"You have access to the carry bit in the program status word register." True, but you have no guarantee that the carry bit at the start of a 'C' statement will necessarily have anything to do with the result of any particular arithmetic operation in the preceding 'C' statement. If you need that sort of direct register control, then you must write in assmebler!
True; the only reason that the variable "c" exists is to try to snag the carry flag before later ADDs in the loop control code change it. And the success of that scheme, of course, is highly dependent on your code generator. You'll be looking at the assembly output anyway; might as well just write the routine in assembler to start with. Another way to tackle the problem is to do the U8 addition in a U16, so you wind up with the carry bit in an actual C variable, instead of relying on quirks of the compiler and architecture:
void U48AddEq (U8 data* dst, U8 data* src, U8 len) { U16 temp = 0; while (len--) { temp += dst[len] + src[len]; dst[len] = (U8)temp; temp >>= 8; } }