masm中的选择排序问题

selection sort issues in masm

我正在开发一个程序。尝试在 Visual Studio 2010 年使用 MASM 在程序集中进行选择排序,但我遇到了问题。每当我将条件从降序更改为升序排序时,程序都会给出错误的答案。我正在尝试更正此问题,我有代码,但我也有另一种语言的选择排序代码,我正在尝试从中进行转换。该语言是网站上的 C++。我想知道如何将使用 min 作为索引的语句转换为汇编中的数组。我已经等了两天了。我需要帮助的人。我仍在研究算法。这是代码:

.386
.model flat,stdcall
.stack 100h

printf proto c arg1:ptr byte, printlist:vararg

.data
printmessage db "Selection Sort",0
fmtmsg1 db "%d",0
fmtmsg2 db 0dh,0ah,0

array dword 9,4,6,8,1,0
arraylength dword 5

temp dword ?
min dword ?


.code
public main
main proc
     ;invoke printf,addr fmtmsg1,addr printmessage
     ;invoke printf,addr fmtmsg2

     mov esi,offset array
     mov ecx,0   ; outerloop
     mov edx,0   ; innerloop

     mov edx,ecx ; innerloop for loop condition variables 

innerloop:
     mov ebx,5
     sub ebx,1  ; outerloop for loop condition variables

     add edx,1  ; innerloop for loop condition variables
     cmp edx,5
     jge outerloop

     mov eax,[esi]     ;9   9,4,6,8,1,0
     cmp eax,[esi + 4] ;4
     Jge noexchange
     mov min,edx

     cmp min,ecx
     je noexchange

      ;exchange values   
      xchg eax,[esi + 4]        
      mov [esi],eax     

noexchange:
      add esi,4           
      jmp innerloop

outerloop:
     mov esi,offset array
     mov edx,0  ; reset innerloop counter

     inc ecx
     cmp ecx,ebx
     jne innerloop


    mov esi,offset array

loop3:
     mov eax,[esi]
     push edx
     invoke printf,addr fmtmsg1,eax
     pop edx

     add esi,4
     inc edx
     cmp edx,5
     jne loop3

     ret
main endp
end main

C++ 代码我试图了解如何使用最小值作为 MASM 中数组的索引。

这是我正在使用的代码:

void selectionSort(int arr[], int n) {
      int i, j, minIndex, tmp;    
      for (i = 0; i < n - 1; i++) 
      {
            minIndex = i;
            for (j = i + 1; j < n; j++)
                  if (arr[j] < arr[minIndex])
                        minIndex = j;

            if (minIndex != i) 
            {
                  tmp = arr[i];
                  arr[i] = arr[minIndex];
                  arr[minIndex] = tmp;
            }
      }
}

我试过了,但无法修复您的汇编代码,所以我将您的 C++ 算法直接翻译成 Visual Studio 2010 C++ 控制台项目中的汇编代码。重要:

  • 我分别使用 ESI、EDI 和 EBX,而不是 i、j 和 minIndex。
  • 因为数组项(数字)是 4 个字节长,i++ 是 "add ESI,4",j++ 是 "add EDI,4"。
  • 两个循环(fori 和 forj)需要 "n" 才能知道结束。因为我使用的是反向计数器,所以有必要使用两个 "n",每个 "for"("ni" 代表 "fori","nj" 代表 "forj").

代码如下:

void selection_sort () {
int arr[5] = {1,5,2,4,3},
    n = 5,                 // ARRAY LENGTH.
    ni,nj,                 // ARRAY LENGTH FOR "FORI" AND "FORJ".
    i, j, minIndex;    

__asm {      lea  esi, arr                         ;I = 0 (ESI USED AS I).
             mov  eax, n
             mov  ni, eax                          ;N.
         fori:
             mov  ebx, esi                         ;MININDEX = I (EBX USED AS MININDEX).

                 mov  edi, esi                     ;J = I (EDI USED AS J).
                 add  edi, 4                       ;J = I+1.
                 mov  eax, n
                 mov  nj, eax                      ;N.
             forj:

             ;IF ( ARR[ J ] < ARR[ MININDEX ] ).
                 mov  eax, [ edi ]                 ;EAX = ARR[ J ].
                 mov  edx, [ ebx ]                 ;EDX = ARR[ MININDEX ].
                 cmp  eax, edx
                 jae  nextj                        ;IF ( ARR[ J ] >= ARR[ MININDEX ] ).

                 mov  ebx, edi                     ;ELSE: MININDEX = J.

             nextj:
             ;FOR ( J = I+1; J < N; J++ ).
                 add  edi, 4                       ;J++.
                 dec  nj                           ;REVERSE COUNTER.
                 jnz  forj                         ;IF (J < N) JUMP.

         ;IF ( MININDEX != I ).
             cmp  ebx, esi  
             je   nexti                            ;DON'T EXCHANGE.

             ;EXCHANGE ARR[ I ] AND ARR[ MININDEX ].
                 mov  eax, [ esi ]                 ;EAX = ARR[ I ].
                 mov  edx, [ ebx ]                 ;EDX = ARR[ MININDEX ].
                 mov  [ esi ], edx                 ;ARR[ I ] = ARR[ MININDEX ].
                 mov  [ ebx ], eax                 ;ARR[ MININDEX ] = ARR[ I ].

         nexti:
         ;FOR ( I = 0; I < N-1; I++ ).
             add  esi, 4                           ;I++.
             dec  ni                               ;REVERSE COUNTER.
             cmp  ni, 1                            ;MUST NOT REACH 0.
             ja   fori                             ;IF I < (N-1) JUMP.
}
}