0

So, I have a task that I need to convert from string for example string "542215" to int 542215 or with any other ASCII symbols. I am kindof new to assembly programming so, I have almost no clue to what I am doing with it, but I wrote my experimental code.

int main(int argc, char** argv) 
{

int Letters;
    char* argv1 = argv[1];

    if (argc < 2) {
        printf("Nepateiktas parametras*/\n");
        return(0);
    }
    __asm {

        push eax
        push ebx
        push ecx

        xor ecx, ecx           
        mov eax, argv1  

    NextChar:
        movzx eax, byte ptr [esi + ecx]
        test eax, eax
        jz Done

        push ecx

        sub eax, 48
        push eax
        call PrintIt
        
        pop ecx
        inc ecx
        jmp NextChar
    
    Done:
        pop ecx
        pop ebx
        pop eax

    PrintIt:
        mov[Letters], eax

            pop ecx
            pop ebx
            pop eax

    };

    printf("Count of letters in string %s is %d\n", argv[1], Letters);

    return(0);
}

and I am getting error that "Run-time check failure #0 - The value of ESP was not properly saved across a function call. This is usually a result of calling a function declared with one calling convention with a function pointer declared with a different calling convention.

This error basicly gives me 0 ideas what is going on, or what even ESP is, so any help would be appreciated with my code.

Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
U-plus-1F92C
  • 1
  • 1
  • 2
  • I don't know x86 assembly to well (I think that's what you're using) but this might be useful for x86 assembly: [link](https://stackoverflow.com/questions/19309749/nasm-assembly-convert-input-to-integer/19312503#19312503) – NO_GUI Dec 05 '20 at 22:02
  • `PrintIt` is not a function, it does not return. Also, you fall through into it. – Jester Dec 05 '20 at 22:06
  • Write the code in C, then compile with the option to save the assembler listing ([`/FA`](https://learn.microsoft.com/en-us/cpp/build/reference/fa-fa-listing-file?view=msvc-160) for MSVC). That will show how the compiler does it, and you can build on it from there. – dxiv Dec 05 '20 at 22:46

1 Answers1

2
  1. you don't need to push/pop registers around your whole asm statement; MSVC already notices which registers you modify.

  2. You're popping the registers twice at the end, when execution falls through from Done: to PrintIt. Or even worse, on strings of non-zero length, you're leaving the asm statement via a path of execution that does 3 pushes at the start, push ecx, push eax, call PrintInt, and then 3 pops. So one of your register-restores is actually reloading the return address pushed by call, and leaving 3 pushed values on the stack.

  3. If you don't know that ESP is the stack pointer, one of x86's 8 general-purpose integer registers, you need to continue reading an intro to basic x86 asm before using stack instructions like push and call.

    Also something about the fact that labels aren't the same thing as functions, and how execution continues to the next instruction.

And BTW, int->string will involve a multiply by 10. See NASM Assembly convert input to integer? for the standard algorithm and an asm implementation.

Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
  • Why is the OP loading `EAX` (`mov eax, argv1`) instead of `ESI` that they are using (`movzx eax, byte ptr [esi + ecx]`) ? – Sep Roland Dec 05 '20 at 23:18
  • 1
    @SepRoland: I have no clue, I stopped looking at the details after seeing no multiply, and the total showstopper of `call PrintIt` leaving the asm block, or the other way out of the loop popping twice.. I was going to just comment about needing to understand what the stack is to be able to use asm, but it turned into a minimal answer so I posted it that way. I have no interest in finding all the bugs in this, but since you mention it the actual loop structure is actually viable if inefficient. I did link another answer that explains how to do string->integer, no need to repeat myself here. – Peter Cordes Dec 05 '20 at 23:37