strcmpPGM  or  strcmpFLASH

Purpose: Alphabetically compare a character string in SRAM with one in FLASH.
Assumes: Both are ASCIIz (i.e., ASCII NULL-terminated) strings.
Passed: R25:R24  BYTE *   szPtrSRAM pointer to the buffer containing string in SRAM
R23:R22 BYTE * szPtrFLASH   pointer to the 328P FLASH buffer containing the second ASCIIz string OR
R26:R23:R22 BYTE * szPtrFLASH the 1284P or 2560 FLASH source address with the second ASCIIz string
Returns:   R24 CHAR cResult less than 0 when String#1 alphabetically preceeds String#2 OR
equal to 0 when the strings are same length and have identical BYTEs OR
greater than 0 when String#1 alphabetically follows String#2
Alters: R25, R26, R27, R30, R31, and the FLAGs (the "T" FLAG, specifically)
Example: 
.ORG  0x1000

CompareStrings:
   ADIW    R26, 0                 ; If 'X' is zero, the command line has nothing
   BREQ    ACompare_Ret           ;  to be checked, so just exit immediately
   MOVW    R24, R26               ; Transfer the buffer pointer to R25:R24 and
   LDI     R22, ' '               ;  set the search character in R22, then try
   CALL    AParseValueAfter       ;  to parse a value after the first space
   SBRS    R21, BIT_PV_VALID      ; Exit if the parser says "nothing there"
Compare_Ret:
   RET

   MOVW    R30, R22               ; Save the FLASH address specified
   MOVW    R24, R26               ; Point to the BYTE after the parsed string
   LDI     R22, '"'               ; Specify the string starting delimiter BYTE
   CALL    Astrchr                ; Search for the first occurrence of a double
   BREQ    ACompare_Ret           ;  quote character; exit if none found

   ADIW    R24, 1                 ; Advance pointer to the BYTE after the '"'
   MOVW    R22, R30               ; R23:R22 = start of the string in FLASH
   CALL    AstrcmpPGM             ; Do the comparison
   LDI     R19, ' '               ; Output a single space before the hex BYTE
   MOV     R22, R24               ; Move the results BYTE returned to R22
   LDI     R25, ACSZ_Result >> 8
   LDI     R24, ACSZ_Result & 0xFF
   CALL    APrintDescAndHexBYTE   ; Output the string and the result BYTE then
   JMP     APrintNewLine          ;  a Carriage Return and Line Feed and exit

CSZ_Result:  .STRING  "strcmpPGM() returned"
Test it:
m>DP+ 0x3A90 48
FLASH (program memory) contents:
3A90:  73 65 74 29 00 45 45 50-52 4F 4D 00 46 4C 41 53  set).EEPROM.FLAS
3AA0:  48 00 46 4C 41 53 48 20-28 70 72 6F 67 72 61 6D  H.FLASH (program
3AB0:  20 6D 65 6D 6F 72 79 29-00 53 52 41 4D 00 53 52   memory).SRAM.SR
m>@ 4096 0x3A9C   "FLASH
strcmpPGM() returned 0x00
m>@ 4096 0x3A95  "EEPROM
strcmpPGM() returned 0x00
m>@ 4096 0x3A95 "EEPROM0
strcmpPGM() returned 0x30
m>@ 4096 0x3A95 "EEPRO
strcmpPGM() returned 0xB3
m>@ 4096 0x3A95 "EEPROL
strcmpPGM() returned 0xFF
m>@ 4096 0x3A95 "EEPROm
strcmpPGM() returned 0x20
m>@ 4096 0x3A95 "EEPRON
strcmpPGM() returned 0x01
m>@ 4096 0x3A95 "EE
strcmpPGM() returned 0xB0
m>                                                                              
Notes: Less than zero means that cResult, the signed result returned in R24, is 0x80 through 0xFF (i.e., the most significant bit is set.)            
More than zero means that cResult is 1 through 0x7F (= 127.)
The comparison is case-sensitive.
Dropin: 
(setup
code)
;   Setup for the strcmpPGM() or strcmpFLASH() call:
; Passed:      R25:R24 BYTE * szPtrSRAM  pointer to string in SRAM
;              R23:R22 BYTE * szPtrFLASH pointer to string in 328P FLASH  OR
;          R26:R23:R22 BYTE * szPtrFLASH pointer to string in 1284P or 2560 FLASH
; Returns:         R24 CHAR   < 0 if SRAM string alphabetically preceeds PGM string
;                             = 0 if the strings are same length and identical
;                             > 0 if SRAM string alphabetically follows PGM string
; Alters:  R25, R26, R27, R30, R31, and the FLAGs ("T", specifically)
Also see:  The strcpyPGM, strlenPGM, strcmp, strchr, strcpy, and strlen System Functions.