2013-05-16 2 views
0

저는 어셈블리를 배우고 있습니다. 선택 목록을 사용하여 정수 목록을 정렬해야합니다. 스왑 기능을 사용하는데 몇 시간을 보냈지 만 다음 단계에서 내 프로그램이 컴파일이 중단되는 이유를 알 수 없습니다. mov [eax], edx & mov [ebx], ecx. 문제는 정렬 함수와 스왑 함수에 있습니다. 누군가 좀 봐 주시겠습니까? 고마워요!선택 정렬 코드가 작동하지 않는 이유는 무엇입니까?

: -

INCLUDE Irvine32.inc 

MIN_NUM = 10 
MAX_NUM = 200 
LOW_VAL = 100 
HIGH_VAL = 999 

.data 

intro_1   BYTE "Sorting Random Integers", 0 
intro_2   BYTE "This program generates random numbers in the range [100...999], ", 0 
intro_3   BYTE "displays the original list, sorts the list, and calculate the ", 0 
intro_4   BYTE "median value. Finally, it displays the list sorted in descending order.", 0 
prompt_1  BYTE "How many numbers should be generated? [10 ... 200]: ", 0 
error_msg  BYTE "Invalid input", 0 
request   DWORD ? 
sortArr   DWORD MAX_NUM DUP(?) 
cnt    DWORD 0  ;count of elements in array 

displayRes_1 BYTE "The unsorted random numbers:", 0 
displayRes_2a BYTE "The median is ", 0 
displayRes_2b BYTE ".", 0 
displayRes_3 BYTE "The sorted list:",0 


.code 
main PROC 

;introduce the program 
call intro  

;get data 
push MIN_NUM 
push MAX_NUM 
push OFFSET error_msg 
push OFFSET request 
call getRequest 

;generate random integers and put them into the array 
push LOW_VAL 
push HIGH_VAL 
push OFFSET sortArr 
push request 
call fillArray 

;display list 
push cnt 
push OFFSET sortArr 
push request 
push OFFSET displayRes_1 
call displayList 

;sort list - selection sort 
push OFFSET sortArr 
push request 
call sortList_desc 


;display median 

;display list 
push cnt 
push OFFSET sortArr 
push request 
push OFFSET displayRes_3 
call displayList 

    exit ; exit to operating system 
main ENDP 

; *************************************************************** 
;Procedure to introduce the program. 
;receives: none 
;returns: none 
;preconditions: none 
;registers changed: edx 
; *************************************************************** 

intro PROC 
    ;display introductions line 1 
    mov  edx, OFFSET intro_1 
    call WriteString 
    call CrLf 
    ;display introductions line 2 
    mov  edx, OFFSET intro_2 
    call WriteString 
    call CrLf 
    ;display introductions line 3 
    mov  edx, OFFSET intro_3 
    call WriteString 
    call CrLf 
    ;display introductions line 4 
    mov  edx, OFFSET intro_4 
    call WriteString 
    call CrLf 
    call CrLf 

    ret 
intro ENDP 

; *************************************************************** 
;Procedure to get a request from the user. 
;Implementation note: This procedure accesses its parameters by setting up a 
; "stack frame" and referencing parameters relative to the top of the 
; system stack. 
;receives: addresses of parameters on the system stack 
;returns: user input values for the reference 
;preconditions: none 
;registers changed: eax, ebx, edx 
; *************************************************************** 

getRequest PROC 
    push ebp 
    mov  ebp, esp 
    mov  edx, OFFSET prompt_1  
    call WriteString    ;prompt user 
    call ReadInt     ;get user's request 
    call CrLf 
    call CrLf 
    cmp  eax, [ebp+20]   ;valid user input   
    jl  input_notOK 
    cmp  eax, [ebp+16]   ;valid user input 
    jg  input_notOK 
    mov  ebx, [ebp+8]   ;address of request in ebx 
    mov  [ebx], eax    ;store user input to the variable, request 
    jmp  theEnd 
    input_notOK:      
     mov  edx, [ebp+12]  ;address of error_msg in edx 
     call WriteString 
     call CrLf 
     pop  ebp 
     jmp  getRequest 
    theEnd: 
     pop ebp 
     ret 16   
getRequest ENDP 

; *************************************************************** 
; Procedure to put random integers into the array. 
; receives: addresses of parameters on the system stack 
; returns: an array of random integers 
; preconditions: request is the user input we received earlier 
; registers changed: eax, ecx, edi 
; *************************************************************** 

fillArray PROC 
    push ebp 
    mov  ebp, esp 
    mov  ecx, [ebp+8] 
    mov  edi, [ebp+12] 
    call Randomize 
    ;generate random integer for each element in the array 
    ;adapted from Lecture 20 slides 
    randGen: 
     mov  eax, [ebp+16] ;get HIGH_VAL 
     sub  eax, [ebp+20] ;HIGH_VAL - LOW_VAL 
     inc  eax    
     call RandomRange 
     add  eax, [ebp+20] 
     mov  [edi], eax 
     add  edi, 4 
     loop randGen 
    endRandGen: 
     pop ebp 
     ret 16 

fillArray ENDP 

; *************************************************************** 
; Procedure to sort the array 
; receives: addresses of parameters on the system stack 
; returns: an array of sorted integers 
; preconditions: an array filled with random integers 
; registers changed: eax, ecx, edi 
; *************************************************************** 

sortList_desc PROC 
    push ebp 
    mov  ebp, esp 
    mov  edi, [ebp+12] ;address of array in edi 
    mov  ecx, [ebp+8] ;loop control in loop_1 ecx = request-1 
    dec  ecx    ;ecx-1 because single element is also maximum element 
    mov  ebx, 0   ;"index" in ebx (index=k) 

    ;for (int i=k, i<request-1;i++) 
    loop_1: 
     ;find the index of the biggest element 
     ;assume the first element is the biggest (i=k) 
     mov  eax, ebx  ;store biggest index in eax (eax=i=k) 

     ;test against elements after finding the biggest 
     ;for (j = k + 1; j < request; j++) 
     mov  edx, eax 
     inc  edx      ;edx=j=k+1 
     push ecx      ;save ecx register 
     mov  ecx, [ebp+8]   ;loop control in loop_2 ecx = request 

     loop_2: 
     mov  esi, [edi+edx*4]  ;store sortArr[j] in esi 
     cmp  esi, [edi+eax*4]  ;compare sortArr[j] and sortArr[k] 
     jle  not_bigger 
             ;if edx is bigger, it is the new max value 
     mov  eax, edx    ;found new biggest index, replace the old biggest index 
    not_bigger: 
     inc  edx    ;next element 
     loop loop_2 

     ;eax is the maximum index(i), swap it with the current position (k) 
     ;exchange (array[k], array[i]) 
     push [edi+ebx*4]     
     push [edi+eax*4]    
     pop  [edi+ebx*4] 
     pop  [edi+eax*4] 
     pop  ecx   ;restore ecx register 
     inc  ebx   ;next iteration of loop_1 
     loop loop_1  

    pop ebp 
    ret 8 
sortList_desc ENDP 
+0

컴파일이 중단되거나 해당 줄에서 실행되는 동안 충돌이 발생합니까? –

+0

@MichaelDorgan 오류 메시지가 나타납니다. Project.exe가 작동을 멈췄습니다. 문제로 인해 프로그램이 올바르게 작동하지 않습니다. – user2203774

+0

버그를 찾았습니다. – Devolus

답변

2

왜 모든 스왑 기능을 필요합니까 (업데이트 내 코드는 컴파일 이제 문제 해결)?

는 IMO이 또한 스왑 수행해야합니다

push [edi+ebx*4] 
    push [edi+eax*4] 
    pop [edi+ebx*4] 
    pop [edi+eax*4] 

이것은 당신의 세그먼트 폴트를 해결하지 않을 것이다, 그러나 그것은 복잡성을 줄일 수 있습니다.

C 함수에서 이것을 호출합니까? 그렇다면 버그입니다. 나는 이것을 제거하고 그것은 나를 위해 작동합니다.

ret 8 

가 있어야한다 : 당신은 또한이 작업을 수행해서는 안

ret 

컴파일러는 C의 호출 스택을 정리한다. :)

+0

팁을 많이 주셔서 감사합니다! 내 코드가 지금 실행됩니다. =) – user2203774

+0

환영합니다. 저는 수년간 많은 모임을하지 않았기 때문에 좋은 운동이었습니다. :) – Devolus

+0

질문이 하나 더 있습니다. 내가 잘 설명 할 수 있을지 모르겠다. 정렬 된 목록을 인쇄 할 때 프로그램에서 110 개의 정렬 된 정수를 인쇄 할 때까지 모든 것이 잘 보입니다. 나는 주소처럼 보이는 이상한 숫자를 얻기 시작했다 (예 : 543516754, 등). 내가 200 개의 정렬 된 목록을 인쇄했을 때, 나는 "웃는 얼굴"을 잔뜩 가지고있다. 어쨌든이 일을 일으킬만한 것을 생각할 수 있습니까? Microsoft Visual Studio를 사용하고 있습니다. – user2203774

관련 문제