【问题标题】:How to convert string to int in assembly MSVC如何在程序集 MSVC 中将字符串转换为 int
【发布时间】:2020-12-06 07:34:14
【问题描述】:

所以,我有一项任务需要从字符串(例如字符串“542215”)转换为 int 542215 或任何其他 ASCII 符号。我对汇编编程有点陌生,所以我几乎不知道我在用它做什么,但我写了我的实验代码。

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);
}

并且我收到错误消息“运行时检查失败 #0 - ESP 的值未在函数调用中正确保存。这通常是调用使用一种调用约定声明的函数并声明了函数指针的结果使用不同的调用约定。

这个错误基本上给了我 0 个想法,或者甚至 ESP 是什么,所以我的代码将不胜感激。

【问题讨论】:

  • 我不太了解 x86 汇编(我认为这就是您正在使用的)但这可能对 x86 汇编有用:link
  • PrintIt 不是函数,它不会返回。而且,你也会陷入其中。
  • 用 C 语言编写代码,然后使用保存汇编程序列表的选项进行编译(MSVC 为/FA)。这将显示编译器是如何做到的,您可以从那里构建它。

标签: c++ assembly visual-c++ x86 inline-assembly


【解决方案1】:
  1. 您不需要在整个 asm 语句周围推送/弹出寄存器; MSVC 已经注意到您修改了哪些寄存器。

  2. 当执行从Done: 下降到PrintIt 时,您最后会弹出两次寄存器。或者更糟糕的是,在非零长度的字符串上,您将通过一条执行路径离开 asm 语句,该路径在开始时执行 3 个pushes,push ecxpush eaxcall PrintInt,然后是 3流行音乐。因此,您的寄存器恢复之一实际上是重新加载由call 推送的返回地址,并在堆栈上留下 3 个推送的值。

  3. 如果您不知道 ESP 是堆栈指针,它是 x86 的 8 个通用整数寄存器之一,您需要继续阅读基本 x86 asm 的介绍,然后才能使用 pushcall 等堆栈指令。

    还有一些关于标签与函数不同的事实,以及执行如何继续到下一条指令。

顺便说一句,int->string 将涉及乘以 10。有关标准算法和 asm 实现,请参阅 NASM Assembly convert input to integer?

【讨论】:

  • 为什么 OP 加载的是EAX (mov eax, argv1) 而不是他们正在使用的ESI (movzx eax, byte ptr [esi + ecx])?
  • @SepRoland:我不知道,在看到没有乘法后我停止查看细节,call PrintIt 的总显示停止器离开了 asm 块,或者循环弹出两次..我只想评论需要了解堆栈才能使用asm,但它变成了一个最小的答案,所以我以这种方式发布了它。我没有兴趣找到其中的所有错误,但既然你提到它,如果效率低下,实际的循环结构实际上是可行的。我确实链接了另一个解释如何执行字符串->整数的答案,无需在这里重复自己。
猜你喜欢
  • 2016-08-27
  • 2017-06-06
  • 2015-11-12
  • 2018-05-08
  • 1970-01-01
  • 1970-01-01
  • 2022-06-27
  • 2011-04-28
相关资源
最近更新 更多