我正在试图弄清楚如何对程序中的角色进行排序。有些原因我认为我的排序搞乱了,因为当我把它放在程序中时就崩溃了,但是当它不在程序中它运行得很好。
现在这里是带有排序参数的cpp文件:
extern "C" void Sort (char [] [11], char [], double [], long);
这是我在汇编中的排序
_Sort proc
mov eax, [esp + 8]
cmp eax, 1
jle L1
push ebp
mov ebp, esp
mov edx, 1
imul edx, Row
mov Count, edx
imul edx, Column
push edx
cld
L1:
call _comp
cmp ebx, 1
jz L1
add esp, 4
pop ebp
L2:
ret
_Sort endp
_Comp Proc
mov edx, 0
mov Count, 0;
L3:
mov edi, offset _pArray1
mov esi, pArray
add esi, edx
mov ecx, Column
rep movsb
add edx, Column
inc Count
mov edi, offset _pArray2
mov ecx, Column
rep movsb
mov edi, offset _pArray1
mov esi, offset _pArray2
mov ecx, Column
repz cmpsb
jge L4
call _Switch
mov ebx, 1
jmp L5
L4:
mov ebx, 0
mov eax, Done
sub eax, Column
cmp edx, eax
jz L5
jmp L3
L5:
ret
_Comp endp
_Switch proc
mov edi, pArray
add edi, edx
sub edi, Column
mov esi, offset _pArray2
mov ecx, Column
rep movsb
mov esi, offset _pArray1
mov ecx, Column
rep movsb
mov esi, [ebp + 12]
add esi, Count
dec esi
mov cl, [esi]
xchg cl, [esi +1]
mov [esi], cl
ret
_Switch endp
答案 0 :(得分:0)
我只是指出了一些在阅读代码时显而易见的问题,所以我看起来并不多,特别是当你使用既不显示也不看似初始化的变量时。
首先调用函数时的堆栈:
sp+ 0 = caller return address
sp+ 4 = char [] [11]
sp+ 8 = char []
sp+ c = double []
sp+10 = long
所以你开始你的代码,你检查的第一件事是指针char []
等于1.我想这不是你想要的。
mov eax, [esp + 8]
cmp eax, 1
如果这是真的,可能不会发生,但它可能为null,那么你执行这段代码:
L1:
call _comp ; we call _comp which uses ebp from the parent function, so it is to be considered not as initialzed *BAM*
cmp ebx, 1 ; why should ebx be 1? You never initilized it, but maybe it is a random value frmo the caller?
jz L1
add esp, 4 ; you are now corrupting the stack
pop ebp ; corrupting it even more
L2:
ret ; and jump back to where char[] points to. *BAM*
现在假设没有采取分支,我们继续在这里:
push ebp
mov ebp, esp ; setup the stackframe, which is ok.
mov edx, 1
imul edx, Row ; Where does Row com from? Is it initlized? Where?
mov Count, edx ; Save the value in Count, but...
imul edx, Column
push edx ; ?
cld
L1:
call _comp ; ... here we call _comp which first instruction is, to initialize Count again.
....
所以我建议重新考虑这段代码,添加注释以便知道它应该做什么,然后在调试器中运行它来检查它是否正在按照你认为的那样做。