我有这个功能,而且大多为内联汇编。
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,它有时意味着在上面的行至点,所以有可能在“流行ESP”。 如果你能帮助我,这将会是巨大的。 谢谢,iDomo。
您不能正确地管理堆栈指针。 特别是,你要调用malloc
不平衡堆栈,你pop esp
结束了弹出错误值到esp
。 因此,访问冲突,当您尝试发生ret
从一个无效的堆栈(CPU不能读取的返回地址)。 目前还不清楚为什么要推动和弹出esp
; 那一事无成。
当你发现,你永远不应该使用指令POP ESP - 当你看到,在代码中,你知道的东西极其错误的发生。 当然,调用asseembler代码中的malloc也相当糟糕的事情 - 你有例如忘记检查,如果它返回NULL,所以你可能会崩溃。 坚持你的汇编程序之外 - 和检查NULL,它更容易调试“的第54行中的文件mycode.c中无法分配内存”比“某处在汇编中,我们得到了一个
下面是一些改进的意见,应该加快你的循环了一下:
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
}
}
改进:乘以四的每一个回路删除。 只是增加esi
代替。 使用递减的ECX,而不是increament,并与循环前成员加载它。 这使得在循环只是一个跳跃,而不是两个的使用。 从EDX删除reduntant动,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
}
}