使用选择排序算法实现一个函数(在汇编中),该函数按升序对给定的整数数组进行排序。函数的输入是arraySize和arrayOfIntegers。该函数将在排序时重新排列数组中的数字。我确定我能够计算第二个值中的最小值的索引(我已调试以检查)。但是,我不能将min和当前索引值交换。我读过类似的问题,但我似乎无法得到它 - 它已经过了3天而且我无法得到它。我对汇编语言非常陌生,并且非常感谢他们的帮助。谢谢,麻烦您了 我的交换从END_FOR_2开始:
void array_sort( int arrayOfIntegers[], int arraySize )
{
int temp;
__asm{
push eax
push ebx
push ecx
push edx
push esi
push edi
// BEGIN YOUR CODE HERE
// Note: You can safely use the 6 registers listed above as well
// as the variable temp in your code, if needed.
mov esi, 0
mov edi, 0
mov ecx, 0
mov eax, 0
mov ebx, arrayOfIntegers
mov edx, arraySize
dec edx
FOR_1:
cmp esi, edx
jg END_FOR_1
mov edi, esi
FOR_2:
inc esi
mov eax, esi
dec esi
WHILE_2:
cmp eax, arraySize
jge END_FOR_2
IF_1:
mov ecx, dword ptr [ebx + eax*4]
cmp ecx, dword ptr [ebx + edi*4]
jg END_IF_1
mov edi, eax
END_IF_1:
inc eax
jmp WHILE_2
END_FOR_2:
mov eax, dword ptr[ebx + 4*edi]
mov ecx, dword ptr[ebx + 4*esi]
IF_2:
cmp edi, esi
je END_IF_2
mov temp, ecx
mov ecx, dword ptr[ebx + 4*edi]
mov eax, temp
END_IF_2:
inc esi
jmp FOR_1
END_FOR_1:
// END YOUR CODE HERE
pop edi
pop esi
pop edx
pop ecx
pop ebx
pop eax
}
}
答案 0 :(得分:0)
如果代码中没有任何评论,那么任何人都需要做很多工作来弄清楚你使用每个寄存器的内容。
IF_2
中的实际错误就像它一样。您将刚刚找到的最小值eax
和下一个要排序的位置([ebx + 4*esi]
)的值加到ecx
中。然后你有一些愚蠢的代码写入然后从temp
读取,而不必写入数组中的任何一个位置。这应该有效:
# IF_2:
# cmp edi, esi # more efficient to just unconditionally do stuff
# je END_IF_2
mov eax, dword ptr[ebx + 4*edi] # or this value is already in ebp from the search loop
mov ecx, dword ptr[ebx + 4*esi]
mov dword ptr[ebx + 4*edi], ecx # exchange values
mov dword ptr[ebx + 4*esi], eax
# END_IF_2:
其他一些显而易见的事情:
xor
将其归为自身,而不是使用即时数据的mov
insn,将效果归零会更有效。mov eax, esi
和inc eax
。或lea eax, [1+esi]
。不是inc
/ mov
/ dec
。我认为你的WHILE_2
会扫描数组其余部分中的最小元素。最好将当前最小值保留在寄存器中,而不是每次都使用dword ptr [ebx + edi*4]
作为cmp
的输入。所以你的循环可能是
mov ebp, dword ptr [ebx + edi*4] # ebp = current min
WHILE_2:
inc eax
cmp eax, arraySize
jge END_FOR_2
mov ecx, [ebx + eax*4]
cmp ebp, ecx
jg WHILE_2 # go to next iteration
# IF_1: if (arr[cur] < min) { minpos = cur; min=arr[cur]; }
mov edi, eax # new minpos
mov ebp, ecx # new minval
END_IF_1:
jmp WHILE_2
请注意,eax
在与以前不同的地方递增,我使用了ebp
。这允许重组在共同路径上放少一条指令(无条件jmp
)。
如果你不能使用ebp
(比如你需要使用帧指针进行编译),那么将不同的值溢出到内存中,并在循环后重新加载它。或者只写64位代码,因为它是2015年以及唯一不能在64位模式下运行的x86 CPU超过10年。 (甚至Atom CPU现在都支持64位)。但无论如何,如果你的寄存器用尽了,那么很少将一些常用的内容泄漏到内存中,而不是每次都通过紧密循环使用的值。
另外,我可能编写了循环来增加指针,而不是使用索引寻址模式。 minpos
可以是指针而不是偏移量。然后,您不需要在ebx
中保留基址,以及两个索引。