1

I've got this code which should change an uppercase letter to a lowercase letter:

void tolower(char *text)
{
    _asm
    {
        mov esi, text;
        mov ecx, 0;
        mov bl, 32;
      opakuj:
        cmp [esi + ecx], 0;
        je konec;
        cmp [esi + ecx], 97;
        jbe dolower;
        add ecx, 1;
        jmp opakuj;

      dolower:
        mov [esi + ecx], bl;
        add ecx, 1;
        jmp opakuj;
      konec:
    }
}

mov [esi + ecx], bl doesn't work. I get an

access violation writing error

What am I doing wrong?

P.S.: I can't use another array or pointer or something like that. I have to rewrite that char.

zx485
  • 28,498
  • 28
  • 50
  • 59
  • Could it be that you are trying to modify a string that is in read-only memory, like a literal string? something like `tolower("HELLO WORLD");` ? You should not try to modify literal strings, only copies. – Rudy Velthuis May 15 '16 at 14:50

2 Answers2

2

One solution would be isolating the lowercase chars and clearing or setting the bit 0x20 with an AND(uppercase) or OR(lowercase), respectively, like described in this SO answer: "How to access a char array and change lower case letters to upper case, and vice versa".

void tolower(char *text)
{
  _asm
  {
    mov esi, text;
    mov ecx, -1;
  opakuj:
    inc ecx;
    cmp [esi + ecx], 0;       // end of string
    je konec;
    cmp [esi + ecx], 65;      // lower bound for uppercase chars
    jb opakuj;
    cmp [esi + ecx], 90;      // upper bound for uppercase chars
    ja opakuj;
    ; and [esi + ecx], 223;   // 11011111 binary - sets uppercase
    or [esi + ecx], 32;       // 00100000 binary - sets lowercase
    jmp opakuj
  konec:
  }
}
Community
  • 1
  • 1
zx485
  • 28,498
  • 28
  • 50
  • 59
  • @ValentinEmilCudelcu: Sorry. I updated my solution. Now it converts all uppercase letters to lowercase letters. 223 is the bitwise NOT of 32. – zx485 May 15 '16 at 13:09
  • Thanks. I figured out how to do it! Second change I made was : cmp [esi + ecx], 65; , cmp [esi + ecx], 90; – Valentin Emil Cudelcu May 15 '16 at 13:11
  • @ValentinEmilCudelcu: I had to do another fix concerning the `Jcc` jumps. See above. – zx485 May 15 '16 at 13:13
  • It still doesn't change that UpperCase letter :/ – Valentin Emil Cudelcu May 15 '16 at 13:21
  • @zx485 Your code doesn't work. Values in the range [97,122] are already lowercase, and you redundantly make them lowercase! What your code needs is testing for uppercase range [65,90]. – Sep Roland May 15 '16 at 13:38
  • @SepRoland: Yes. You're right. I fixed that... I had that all inverted in the beginning :-( – zx485 May 15 '16 at 13:41
  • @ValentinEmilCudelcu: I incorporated the fix suggested by Sep Roland. I hope it will work now. Sorry for that. – zx485 May 15 '16 at 13:44
0

Changing mov [esi + ecx], bl to add [esi + ecx], bl corrects the error.

But your program is still not robust. (E.g. what if the input is a number character?)

WhatsUp
  • 1,618
  • 11
  • 21
  • My bad, I tried add [esi+ecx],bl to and it doesn' work. Let assume that will be only character from A to Z. – Valentin Emil Cudelcu May 15 '16 at 12:47
  • 1
    That's strange. The code compiles and runs correctly on my computer. Are you testing it like `tolower("ABCDEF")`? Don't do that. Instead, create a `char test[] = "ABCDEF"`, and then do `tolower(test)`. – WhatsUp May 15 '16 at 12:49
  • IS your string zero terminated? perhaps the function does, what you want, but doenst stop where the string is ended, and you exceed it ? – Tommylee2k May 15 '16 at 12:50
  • @Tommylee2k This sounds like a probable reason. – WhatsUp May 15 '16 at 12:51
  • 1
    I used char *string = "AbCD". The erorr was beucase I gave a pointer instead of an array of chars. I'm so stupid. – Valentin Emil Cudelcu May 15 '16 at 12:52
  • The error was because your "AbCD" is a string literal, which are usually in read-only memory, not because you used a pointer. `char *` is a pointer, so that is fine. – Rudy Velthuis May 15 '16 at 14:54