strlenPGM  or  strlenFLASH

Purpose: Determine the number of BYTEs in a string in PROGRAM, or FLASH, memory.
Assumes:  Strings in FLASH can be terminated with a BYTE of 0, 0xFE, or 0xFF.
Passed:     R25:R24  BYTE *   bPtrFLASH  pointer to the 328P FLASH address at which to begin OR
R26:R25:R24  BYTE *   bPtrFLASH  pointer to the 1284P or 2560 FLASH address at which to begin
Returns: R25:R24  WORD wCount the BYTE count, which may be zero.
FLAGS  ZERO flag set (TRUE) when length is zero (and R25:R24 = 0) OR
clear (FALSE) when length is > 0 (and R25:R24 > 0)
Alters: Only R24, R25 and the FLAGs
Example: 
.ORG  0x1000

CheckPGMLength:
   ADIW    R26, 0                ; If 'X' is zero, no parameter was passed on the
   BREQ    ACheckPGMLength_Ret   ;  command line, so just exit immediately
   MOVW    R24, R26              ; Point R25:R24 at buffer to be parsed
   CALL    AParseValue           ; Extract one numeric value from the string
   SBRS    R21, BIT_PV_VALID     ; If no value was parsed, just exit
   RJMP    ACheckPGMLength_Ret   ; The ULONG value returned in R25:R24:R23:R22

   MOVW    R24, R22              ; The FLASH pointer is the Low WORD of that
   CALL    AstrlenPGM            ; The System Function being demonstrated
   CALL    ADumpRegisters        ; Optional (for FLAGs); toggle on with '}'
   CALL    APrintWORD            ; Print the WORD returned in R25:R24
   LDI     R25, ACSZ_BYTEs >> 8
   LDI     R24, ACSZ_BYTEs & 0xFF
   CALL    APrintFLASHASCIIz     ; The string below, ending in CR, LF

CheckPGMLength_Ret:
   RET

CSZ_BYTEs:  .STRING  " BYTEs in the FLASH string\n"
Notes: Strings in PROGRAM memory are considered terminated if they end in 0, 0xFE or 0xFF, noting that 0xFF is the value of unprogrammed FLASH.
The string may begin with a NULL, 0xFE, or 0xFF, which are all valid and will return zero length.
EEPROM addresses beyond the end of protected FLASH (i.e., for Version 3.01 of MIRTOS: 0x4000 or greater for the 328P, 0x1AE00 or greater for the 1284P, or 0x3AC00 or greater for the 2560) will always readback as 0xFF. This table has more range details.
The ZERO flag has already been set or cleared, so no comparison of R25:R24 need be done.
Dropin: 
(setup
code)
;   Setup for the strlenPGM() or strlenFLASH() call:
; Passed:      R25:R24 BYTE * bPtrFLASH 328P FLASH address at which to begin counting
;          R26:R25:R24 BYTE * bPtrFLASH 1284P or 2560 FLASH address at which to begin
; Returns:     R25:R24 WORD   wCount, number of BYTEs before the terminator
;  (Also:)        ZERO FLAG   set (TRUE) when length is zero (and R25:R24 = 0)
;                             clear (FALSE) when length is > 0 (and R25:R24 > 0)
; Alters:  Only R24, R25, and the FLAGSs
; Notes:   The terminator BYTE is 0, 0xFE, or 0xFF for PROGRAM strings.
Also see:  The strcpy, strlen, and strlenEEPROM System Functions.