gpt4 book ai didi

C++ 内联程序集运行时检查失败 #0

转载 作者:行者123 更新时间:2023-11-30 00:52:00 25 4
gpt4 key购买 nike

我正在编写一个需要内联汇编代码来反转字符串的 C++ 代码。所以如果我的输入是:“qwerasd”输出应该是“dsarewq”。我想到了使用堆栈来实现它。我的代码是:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void reverseString(char* buffer, int len){

__asm {

push ecx
push edi
push eax

mov ecx, len
mov edi, buffer

top:
mov al, BYTE PTR [edi]
push al
inc edi
loop top

mov ecx, len
mov edi, buffer

refill:
pop al
mov BYTE PTR [edi], al
inc edi
loop refill
}
}

int main() {

char s[64];
char *ptr = s;
int size;

printf("\nEnter text: ");
scanf("%s", s);
size = strlen(s);

reverseString(ptr, size);

printf("\nThe new text is: %s\n\n", s);
exit(0);
}

我正在尝试将字符一个一个地压入堆栈,然后将它们一个一个地弹出并将其存储回字符串中。

当我运行代码时,出现以下错误: 运行时检查失败 #0 - ESP 的值未在函数调用中正确保存。这通常是用一个调用约定声明的函数调用一个以不同调用约定声明的函数指针的结果。

我做错了什么?

最佳答案

除了 Zack 的回答之外,推送 edi 实际上并不是必需的,因为编译器似乎会自动为您执行此操作,至少对于 msvc 而言。

上面代码的另一个问题是,您正在执行一个pop al,它只会将esp 增加一个字节。这显然会导致问题,因为正常的 push pop 操作预计在 32 位下是 4 字节对齐的。当您的函数退出时,它最终会为 ebp 恢复错误的值,它会返回到某个错误的返回地址,随后会发生严重破坏。

你可以这样修复它:

top:
movzx eax, BYTE PTR [edi]
push eax
// ...
refill:
pop eax
mov BYTE PTR [edi], al

编辑:只是为了添加一些说明,al 不是用于push 的有效操作数大小弹出。不确定为什么 msvc 没有给出错误。您的上述程序集最终被翻译成 push eaxpop ax 而不是不平衡的来源。

关于C++ 内联程序集运行时检查失败 #0,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20130775/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com