$NOMOD51 ;------------------------------------------------------------------------------ ; This assembler code shows three versions of a DEC DPTR code. ; A test function is also included. ; Summary: ; Version A: 5 instructions, 10 bytes, 6 cycles (5 if branch taken), carry flag modified ; Version B: 5 instructions, 9 bytes, 6 cycles (5 if branch taken), no flags modified ; Version C: 4 instructions, 9 bytes, 5 cycles (4 if branch taken), no flags modified ; Instruction count without CALL/RET, code may be used as inline ;------------------------------------------------------------------------------ CSEG AT 0 MOV SP, #7 ; Reset value of SP MOV PSW, #0 ; Select register bank 0 LJMP TEST ; Run all 3 tests EXIT_ERROR: ; Endless loop here if error. Set a breakpoint here in debugger/simulator SJMP EXIT_ERROR EXIT_OK: ; Endless loop here if all tests passed. Set a breakpoint here in debugger/simulator SJMP EXIT_OK ;------------------------------------------------------------------------------ ; DEC DPTR Example A (from Craig Steiner) ; 5 instructions, 10 bytes, 6 cycles (5 if branch taken), carry flag modified ;------------------------------------------------------------------------------ DEC_DPTR_A: XCH A,DPL ;Exchange A for DPL DEC A ;Decrement A (which is DPL) CJNE A,#0FFh,_dec_dptr_A2;If A (DPL) is not #0FFh, continue normally DEC DPH ;If A=FFh, we need to decrement DPH _dec_dptr_A2: XCH A,DPL ;Exchange A for DPL (thus saving DPL and restoring A) RET ;------------------------------------------------------------------------------ ; DEC DPTR Example B ; 5 instructions, 9 bytes, 6 cycles (5 if branch taken), no flags modified ;------------------------------------------------------------------------------ DEC_DPTR_B: XCH A, DPL JNZ _dec_dptr_B2 DEC DPH _dec_dptr_B2: DEC A XCH A, DPL RET ;------------------------------------------------------------------------------ ; DEC DPTR Example C ; 4 instructions, 9 bytes, 5 cycles (4 if branch taken), no flags modified ;------------------------------------------------------------------------------ DEC_DPTR_C: INC DPL DJNZ DPL, _dec_dptr_C2 DEC DPH _dec_dptr_C2: DEC DPL RET ;------------------------------------------------------------------------------ ; Sub function used by test loop. Use R6/R7 16bit value to compare with DPTR ; Code is NOT optimized ;------------------------------------------------------------------------------ DEC_R6R7_COMPARE: ; Decrement the 16 bit word in R6(H) R7(L) (ADD -1 (0xFFFF)) MOV A, R7 ADD A, #0FFh MOV R7, A MOV A, R6 ADDC A, #0FFh MOV R6, A ; Compare with the current DPTR value, must be equal MOV A, R6 CJNE A, DPH, EXIT_ERROR MOV A, R7 CJNE A, DPL, EXIT_ERROR ; Return with ACC == 0 if R6/R7 is 0x0000, else return ACC != 0 MOV A, R7 ORL A, R6 RET ;------------------------------------------------------------------------------ ; Test of the DEC DPTR code ;------------------------------------------------------------------------------ TEST: ;------------------------------------------------------------------------------ ; Run test for the first version of DEC_DPTR ;------------------------------------------------------------------------------ TEST_A: MOV DPTR, #0 MOV R7, #0 MOV R6, #0 TEST_LOOP_A: LCALL DEC_DPTR_A LCALL DEC_R6R7_COMPARE JNZ TEST_LOOP_A ; run 65536 loops until R6 and R7 are 0 ;------------------------------------------------------------------------------ ; Run test for the second version of DEC_DPTR ;------------------------------------------------------------------------------ TEST_B: MOV DPTR, #0 MOV R7, #0 MOV R6, #0 TEST_LOOP_B: LCALL DEC_DPTR_B LCALL DEC_R6R7_COMPARE JNZ TEST_LOOP_B ; run 65536 loops until R6 and R7 are 0 ;------------------------------------------------------------------------------ ; Run test for the third version of DEC_DPTR ;------------------------------------------------------------------------------ TEST_C: MOV DPTR, #0 MOV R7, #0 MOV R6, #0 TEST_LOOP_C: LCALL DEC_DPTR_C LCALL DEC_R6R7_COMPARE JNZ TEST_LOOP_C ; run 65536 loops until R6 and R7 are 0 SJMP EXIT_OK END