News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests
NB: Posting URL's See here: Posted URL Change

Main Menu

Title case sample

Started by Vortex, December 29, 2023, 07:40:45 AM

Previous topic - Next topic

Vortex

Hello,

Title case convertion with Poasm :

include TitleCase.inc

.data

LookupTable1    db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
                db 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1
                db 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1
                db 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0
                db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
                db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
                db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
                db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0


LookupTable2    db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
                db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
                db 0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0
                db 0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0
                db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
                db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
                db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
                db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0


sample db 'WHAT/A[CRAZY]{NIGHT}(OF)<PROGRAMMING>?IT~WAS!',0
     
.code

TitleCase PROC uses esi edi ebx string:DWORD

    mov     ecx,1
    mov     esi,OFFSET LookupTable1
    mov     edx,OFFSET LookupTable2
    mov     ebx,ecx
    mov     edi,string
    sub     edi,ebx

@@:
    add     edi,ecx
    movzx   eax,BYTE PTR [edi]
    test    eax,eax
    jz      finish
   
    cmp     BYTE PTR [esi+eax],cl
    jne     CheckTable2
    mov     ebx,1
    jmp     @b

CheckTable2:

    cmp     BYTE PTR [edx+eax],cl
    jne     @b

    or      eax,32
    mov     BYTE PTR [edi],al

    cmp     ebx,ecx
    jne     @b

    sub     eax,32
    mov     BYTE PTR [edi],al
    xor     ebx,ebx

    jmp     @b   
   
finish:

    ret

TitleCase ENDP   

start:

    invoke  TitleCase,ADDR sample
    invoke  printf,ADDR sample

    invoke  ExitProcess,0

END start


jj2007

Nice example, Erol :thumbsup:

There are diverging views on the rules of "titlecasing":
TitleCase proc    The Catcher In The Rye, Pride And Prejudice, Clockwork Orange Are Famous
MB TitleCase$    The Catcher in the Rye, Pride and Prejudice, Clockwork Orange are Famous
titlecase.com      The Catcher in the Rye, Pride and Prejudice, Clockwork Orange Are Famous
titlecaseconverter  The Catcher in the Rye, Pride and Prejudice, Clockwork Orange Are Famous
convertcase.net  The Catcher in the Rye, Pride and Prejudice, Clockwork Orange Are Famous

I am actually a bit surprised that "are" is being capitalised by the online tools. I may have to adapt my own TitleCase$...

Biterider

Hi Erol
When I looked at the code, I noticed that the characters of the two tables do not overlap. 
This means that you can create only one table to save some memory.

Biterider

NoCforMe

Nice example. But I don't think this is particular to Poasm, is it? Looks like it should work with any assembler.
Quote from: jj2007 on December 29, 2023, 08:29:20 AMThere are diverging views on the rules of "titlecasing":
MB TitleCase$    The Catcher in the Rye, Pride and Prejudice, Clockwork Orange are Famous
JJ, your case assignment is the classically correct one, according to English usage consensus (e.g., Strunk & White's The Elements of Style). Articles and prepositions aren't capitalized. (Although "famous" shouldn't be capitalized unless it's actually part of a title.)
Assembly language programming should be fun. That's why I do it.

Biterider

Hi Vortex
Here is a code variant with a combined table  :cool:
align ALIGN_DATA
.const
  TITLE_CASE_TABLE label BYTE
  ;  NUL SOH STX ETX EDT ENQ ACK BEL  BS TAB  LF  VF  FF  CR  SO  SI
  db 000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000
  ;  DLE DC1 DC2 DC3 DC4 NAK SYN ETB CAN BM  SUB ESC FS  GS  RS  US
  db 000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000
  ;  SPC   !   "   #   $   %   &   '   (   )   *   +   ,   -   .   /
  db 004,004,004,004,004,004,004,004,004,004,004,004,004,004,004,004  ;+,/
  ;    0   1   2   3   4   5   6   7   8   9   :   ;   <   =   >   ?
  db 000,000,000,000,000,000,000,000,000,000,004,004,004,004,004,004  ;0..9
  ;    @   A   B   C   D   E   F   G   H   I   J   K   L   M   N   O
  db 004,001,001,001,001,001,001,001,001,001,001,001,001,001,001,001  ;A..O
  ;    P   Q   R   S   T   U   V   W   X   Y   Z   [   \   ]   ^   _
  db 001,001,001,001,001,001,001,001,001,001,001,004,004,004,004,004  ;P..Z
  ;    `   a   b   c   d   e   f   g   h   i   j   k   l   m   n   o
  db 004,002,002,002,002,002,002,002,002,002,002,002,002,002,002,002  ;a..o
  ;    p   q   r   s   t   u   v   w   x   y   z   {   |   }   ~
  db 002,002,002,002,002,002,002,002,002,002,002,004,004,004,004,000  ;p..z
  db 000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000
  db 000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000
  db 000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000
  db 000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000
  db 000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000
  db 000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000
  db 000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000
  db 000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000

The 32 bit code for ANSI strings is
TC_IS_UPPER equ 1
TC_IS_LOWER equ 2
TC_IS_SEPAR equ 4

TC_NEED_UPPER equ 1
TC_NEED_LOWER equ 2

.code

OPTION PROC:NONE
align ALIGN_CODE
TitleCase proc pString:POINTER
  mov ecx, [esp + 4]
  mov al, TC_NEED_UPPER                                 ;Always start with TC_NEED_UPPER
  .repeat
    movzx edx, BYTE ptr [ecx]
    .break .if edx == 0
      mov ah, BYTE ptr [TITLE_CASE_TABLE + edx]
      .if al == TC_NEED_UPPER
        .if (ah & TC_IS_LOWER)
          sub edx, 32
        .endif
        .if !(ah & TC_IS_SEPAR)
          mov al, TC_NEED_LOWER
        .endif
      .else
        .if (ah & TC_IS_UPPER)
          add edx, 32
        .endif
        .if (ah & TC_IS_SEPAR)
          mov al, TC_NEED_UPPER
        .endif
      .endif
    mov BYTE ptr [xcx], dl                              ;Store the result
    add ecx, sizeof BYTE
  .until FALSE
  ret 4
TitleCase endp
OPTION PROC:DEFAULT

Attached to complete source.

Biterider