From: NeedNotReplyHere@nospicedham.xrsevnneqk.cem   
      
   On Mon, 26 Jun 2017 16:25:06 -0700   
   "Benjamin David Lunt" wrote:   
      
   > Along with the other stricmp() thread, where as the task is to   
   > make it fast, how about I change it slightly for something I   
   > am working on.   
   >   
   > I need a small stricmp() in a real mode boot loader.   
   >   
   ...   
      
   >    
   > One thing I thought of is to change the uppercase() to simply   
   > set/clear bit 5 in the char before the compare. For example:   
   >   
   > A = 01000001b   
   > a = 01100001b   
   >   
   > I could simply do an   
   >   
   > or al,00100000b   
   > or   
   > and al,~00100000b   
   >   
   > instead of   
   >   
   > call uppercase   
   >   
      
   Or, an AND 0xDF.   
      
   Or, you could immediately XOR the two values. (This could've been done   
   for the C routine too.) If zero, they're same char, .e.g, JZ. If 0x20,   
   same char, but different case, i.e., CMP with 0x20, then branch.   
      
   I think AND, OR, or XOR are the simplest, but you could consider XLAT.   
   It's a smaller instruction, but it does require you to have space to   
   set up a table somewhere. Technically, it's overkill to do upper- to   
   lower-case, but may reduce bytes used.   
      
   Are you re-using these strings? If so, you don't want to change them   
   directly, but modify their loaded values. If not, uppercase them in   
   place, then compare. That's max three loops, yes?   
      
   > However, is this guaranteed to work? Will setting bit 5 falsely   
   > change a char from a non-alpha character to an alpha character.   
   > No I don't think so. This should work...   
      
   ASCII? Upper and lower are 0x20 apart. The control characters might   
   be changed by a mask with 0x20. EBCDIC doesn't map alphabetic   
   characters nicely. Digits 0 through 9 are in sequence for both ASCII   
   and EBCDIC. This is also a requirement for the C language.   
      
   > In my boot code, I only care if it is equal or not, so no need   
   > for the double compare (two jcc's). However, I would like to keep   
   > this routine somewhat standard so that I can call it from other   
   > code without any assumptions.   
      
   If you say what these strings are for, there might be some   
   simplification for your usage.   
      
   E.g., if for display, you could store the strings in lowercase, and have   
   the display routine uppercase the first character of the string before   
   emitting and automatically append a period, newline, etc. Comparisons   
   with the stored string would then always be in lowercase. I.e., no   
   need for stricmp() but for strcmp().   
      
   > ; =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-   
   > ; this routine compares (case insensitive) two strings   
   > [...]   
      
   Just a quick skim.   
      
   Use of string instructions is good. They're compact, but do require   
   setup.   
      
   If this is for assembly, I'm wondering why you're using -1, 0, 1   
   returns. These are good for C, but for assembly, you'd be better off   
   with setting processor flags for Jcc branch instruction. Is this for   
   C code for Smaller C? ... Yes, they're ASCIIZ, so very likely C code.   
      
   If I was doing this in assembly for size, I'd try to convert the strings   
   to the same case, first, or use some trick to not need a case   
   insensitive comparison. Then, I could use REPE CMPS (and/or REPNE   
   CMPS) to compare the strings, i.e., strcmp() instead of stricmp().   
      
   If I was being really insane, I'd reduce the used character set in my   
   strings to only sixteen characters, map to hex, then pack two hex coded   
   characters per byte. Unpack using AAM 0x10. Decode using XLAT.   
      
      
   Rod Pemberton   
   --   
      
   --- SoupGate-Win32 v1.05   
    * Origin: you cannot sedate... all the things you hate (1:229/2)   
|