Assembly 用汇编语言在函数中排序数组?
使用选择排序算法(在汇编中)实现一个函数,该函数按升序对给定的整数数组进行排序。该函数的输入是arraySize和ArrayOfInTeger。函数将在排序时重新排列数组中的数字。我确信我能够计算第二个值中最小值的索引(我调试以进行检查)。但是,我无法将最小值和当前索引的值交换。我读过类似的问题,但我似乎无法理解——已经三天了,我无法理解。我对汇编语言非常陌生,希望能得到帮助。请原谅我,谢谢你 我的交换从\u末尾开始到\u 2:Assembly 用汇编语言在函数中排序数组?,assembly,x86,Assembly,X86,使用选择排序算法(在汇编中)实现一个函数,该函数按升序对给定的整数数组进行排序。该函数的输入是arraySize和ArrayOfInTeger。函数将在排序时重新排列数组中的数字。我确信我能够计算第二个值中最小值的索引(我调试以进行检查)。但是,我无法将最小值和当前索引的值交换。我读过类似的问题,但我似乎无法理解——已经三天了,我无法理解。我对汇编语言非常陌生,希望能得到帮助。请原谅我,谢谢你 我的交换从\u末尾开始到\u 2: void array_sort( int arrayOfInteg
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
}
}
由于代码中没有注释,任何人都需要做大量工作才能弄清楚您使用每个寄存器的目的 实际的bug看起来像是在
IF_2
中。您将获得刚刚在eax
中找到的最小值,并将下一个位置的值([ebx+4*esi]
)排序到ecx
。然后你就有了一些愚蠢的代码,它先写入然后从temp
读取,而从来没有写入数组中的任何一个位置。这应该起作用:
\IF#u 2:
#cmp edi,esi#更有效地无条件地做事情
#如果第二次会议结束
mov eax,dword ptr[ebx+4*edi]#或该值已在搜索循环的ebp中
mov ecx,dword ptr[ebx+4*esi]
mov dword ptr[ebx+4*edi],ecx#交换值
mov dword ptr[ebx+4*esi],eax
#如果_2:
其他一些显而易见的事情:
- 通过
将reg自身归零比使用即时数据将其归零更有效xor
- 要获得eax=esi+1,请执行
和mov-eax、esi
。或inc-eax
。非leaeax,[1+esi]
/inc
/mov
dec
,而_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
mov ebp,dword ptr[ebx+edi*4]#ebp=当前最小值
而_2:
埃克斯公司
cmp eax,阵列化
jge结束_用于_2
mov ecx,[ebx+eax*4]
cmp-ebp,ecx
jg而_2#转到下一个迭代
#IF_1:IF(arr[cur]
请注意,eax
在与以前不同的位置递增,我使用了ebp
。这允许重构在公共路径上少放一条指令(无条件的jmp
)
如果不能使用ebp
(比如需要在打开帧指针的情况下编译),则将不同的值溢出到内存中,并在循环后重新加载它。或者只写64位代码,因为现在是2015年,唯一不能在64位模式下运行的x86 CPU已经超过10年了。(即使是Atom CPU现在也支持64位)。但无论如何,如果寄存器用完了,就会将不经常使用的内容溢出到内存中,而不是通过一个紧密循环每次使用的值
此外,我可能编写循环以增加指针,而不是使用索引寻址模式minpos
可以是指针而不是偏移量。这样,您就不需要在ebx中保留基址以及两个索引