'ret'指令上的访问冲突
Access violation on 'ret' instruction
我得到了这个函数,它主要由内联asm组成。
long *toarrayl(int members, ...){
__asm{
push esp
mov eax, members
imul eax, 4
push eax
call malloc
mov edx, eax
mov edi, eax
xor ecx, ecx
xor esi, esi
loopx:
cmp ecx, members
je done
mov esi, 4
imul esi, ecx
add esi, ebp
mov eax, [esi+0xC]
mov [edi], eax
inc ecx
add edi, 4
jmp loopx
done:
mov eax, edx
pop esp
ret
}
}
运行后,返回指令出现访问冲突
我用的是vc++ 6,它有时意味着指向上面的行,所以可能在'pop esp'上。如果你能帮我,那就太好了。谢谢,iDomo。
无法正确管理堆栈指针。特别是,您对malloc
的调用使堆栈不平衡,并且您的pop esp
最终将错误的值弹出到esp
中。因此,当您尝试从无效的堆栈(CPU无法读取返回地址)中访问ret
时,就会发生访问冲突。不清楚你为什么要按下和弹出esp
;
正如您所看到的,您永远不应该使用POP ESP指令—当您在代码中看到它时,您就知道发生了严重的错误。当然,在asseembler代码中调用malloc也是一件很糟糕的事情——例如,您可能忘记检查它是否返回NULL,因此您可能会崩溃。把它放在你的汇编器之外-并检查NULL,调试"无法在文件mycode.c中第54行分配内存"比调试"在汇编器的某个地方,我们得到一个
"要容易得多。这里有一些改进建议,可以加快你的循环速度:
long *toarrayl(int members, ...){
__asm{
mov eax, members
imul eax, 4
push eax
call malloc
add esp, 4
mov edx, eax
mov edi, eax
mov ecx, members
lea esi, [ebp+0xc]
loopx:
mov eax, [esi]
mov [edi], eax
add edi, 4
add esi, 4
dec ecx
jnz loopx
mov lret, eax
ret
}
}
改进:在每个循环中移除乘4。只需增加esi
即可。在ecx上使用递减而不是递增,并在循环之前用成员加载它。这允许在循环中只使用一次跳转,而不是两次。从edx移除多余的移动到eax。直接使用eax。
我自己想出了答案。
对于那些有过相同或类似问题的人:
实际的异常发生在用户代码之后,当vc++自动弹出/恢复寄存器到函数被调用之前的状态时。由于我在调用malloc时没有对齐堆栈指针,因此在从堆栈弹出时存在访问冲突。我无法在编辑器中看到这个,因为它不是我的代码,所以它只是作为函数中我的最后一个代码显示。
要纠正这个问题,只需在呼叫后添加一个add esp(先前呼叫的参数大小)。
固定代码:long *toarrayl(int members, ...){
__asm{
mov eax, members
imul eax, 4
push eax
call malloc
add esp, 4
mov edx, eax
mov edi, eax
xor ecx, ecx
xor esi, esi
loopx:
cmp ecx, members
je done
mov esi, 4
imul esi, ecx
add esi, ebp
mov eax, [esi+0xC]
mov [edi], eax
inc ecx
add edi, 4
jmp loopx
done:
mov eax, edx
ret
}
//return (long*)0;
}
优化代码:
long *toarrayl(int members, ...){
__asm{
mov eax, members
shl eax, 2
push eax
call malloc
add esp, 4
;cmp eax, 0
;je _error
mov edi, eax
mov ecx, members
lea esi, [ebp+0xC]
loopx:
mov edx, [esi]
mov [edi], edx
add edi, 4
add esi, 4
dec ecx
jnz loopx
}
}
- 写入位置0x0000000C时发生访问冲突
- 引发异常:读取访问冲突**dynamicArray**为0x1118235.发生
- 链表中写入访问冲突的未知原因
- C++中的openCV Mat访问冲突
- C++尝试深度复制唯一指针时出现内存访问冲突
- C++ 中动态二维数组的访问冲突
- 从嵌套循环中的 std::list 中删除将返回访问冲突
- 写入访问冲突异常
- 在类 12.exe 中0x7B37FF80 (ucrtbased.dll) 引发异常: 0xC0000005:访问冲突读
- 0xC0000005:访问冲突写入位置0xCDCDCDCD动态分配错误
- 读取访问冲突.这0xCDCDCDCD
- 0xC0000005:访问冲突读取位置 0x00000000. 重载 == 运算符的问题
- 插入数组时违反写访问冲突
- 使用 ReadProcessMemory 获取字符串值的访问冲突
- 尝试通过共享指针使用变量时读取访问冲突
- 堆栈上的 C++ 访问冲突写入异常
- 引发异常:写访问冲突. temp 为 nullptr
- 将静态字符数组中的字符分配给动态分配的字符数组 - 访问冲突
- 在C++中删除双向链表的头节点后出现访问冲突异常
- 'ret'指令上的访问冲突