2013-07-23 4 views
2

나는 거품 정렬을 x86 (masm32)에 쓰려고합니다. 정렬이 작동하지 않습니다. 일부 코드를 테스트 한 결과 비교 섹션과 스왑 섹션에서 엉망이 된 것으로 보입니다. 어떤 이유인지 비교 함수는 항상 EAX에 2를 할당합니다. 내가 왜 프로그램을 작동시킬 수 있는지 알아낼 수 있다면.거품 정렬 (masm32), 내가 쓴 정렬 작동하지 않습니다.

미리 도움을 주셔서 감사합니다. 이와

cmp ebx, eax 
    jg swap 

swap: 
    mov [aa + edi * 4h], eax 
    mov [aa + edi * 4h + 4], ebx 
    jmp inner 

이는 g 플래그가 설정되어있는 경우 스왑 점프 -하지만 g 플래그가 하지 경우 스왑을 통해 해당 될

.data 
      aa DWORD 10 DUP(5, 7, 6, 1, 4, 3, 9, 2, 10, 8) 
     count DWORD 0 
; DB 8-bits, DW 16-bit, DWORD 32, WORD 16 BYTE 8 



    .code      ; Tell MASM where the code starts 

; ««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««« 

start:       ; The CODE entry point to the program 

    mov esi, count ;loop count 

    outer: 
     inc esi 
     mov edi, count   
     cmp esi, 9  
     je end_loop 

    inner: ;this loop represents a full pass on the entire array 
     inc edi   
     cmp edi, 9 ;after 9 passes goes to outer loop 
     je outer 

    compare: 
     mov eax, [aa + edi * 4h] ;higher indexed one 
     mov ebx, [aa + edi * 4h - 4h] 

;testing  print chr$(13,10) 
;testing  print str$(eax) 
;testing  print chr$(13, 10) 
;testing  print str$(ebx) 
;testing  print chr$(13, 10) 

     cmp ebx, eax 
     jg swap 

    swap: 
     mov [aa + edi * 4h], eax 
     mov [aa + edi * 4h + 4], ebx 
     jmp inner 

end_loop: 

    ;print out array elements 
    sub esi, esi 
    mov esi, [aa] 
    print str$(esi) 
    print chr$(" ") 
    sub esi, esi 

    mov esi, [aa + 4h] 
    print str$(esi) 
    print chr$(" ") 
    sub esi, esi 

    mov esi, [aa + 4h * 2] 
    print str$(esi) 
    print chr$(" ") 
    sub esi, esi 

    mov esi, [aa + 4h * 3] 
    print str$(esi) 
    print chr$(" ") 
    sub esi, esi 

    mov esi, [aa + 4h * 4] 
    print str$(esi) 
    print chr$(" ") 
    sub esi, esi 

    mov esi, [aa + 4h * 5] 
    print str$(esi) 
    print chr$(" ") 
    sub esi, esi 

    mov esi, [aa + 4h * 6] 
    print str$(esi) 
    print chr$(" ") 
    sub esi, esi 

    mov esi, [aa + 4h * 7] 
    print str$(esi) 
    print chr$(" ") 
    sub esi, esi 

    mov esi, [aa + 4h * 8] 
    print str$(esi) 
    print chr$(" ") 
    sub esi, esi 

    mov esi, [aa + 4h * 9] 
    print str$(esi) 
    print chr$(" ") 
    sub esi, esi 

exit 


; ««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««« 

end start      ; Tell MASM where the program ends 

답변

0

하나의 명백한 문제는 바로 여기 설정하므로 정확하게 동일한 코드가 실행됩니다. 짐작할 때, 두 항목이 이미 정렬되어 있다면 교환을 건너 뛰는 것과 같은 것이 아마도 jle inner 일 것입니다.

편집 : 다시 살펴보면 다른 명백한 문제가있는 것처럼 보입니다. C와 같은 것을 생각해보고 eax (compare)을로드 할 때 주소로 base을 사용하십시오. (개념) 당신은 수행

eax = *base; 
ebx = *(base + 4); 

그런 다음 swap에서 당신이 할 :

*base = eax; 
*(base - 4) = ebx; 

이뿐만 아니라 분명히 잘못된 것입니다. 두 변수를 바꾸려면 다음과 같은 것이 필요합니다.

*base = ebx; 
*(base + 4) = eax; 
+0

고마워요! 나는 그것을 바로 바꿀 것이다. 그러나 EAX를 출력 할 때 왜 항상 2인지는 모르겠다. (비교 함수에서, 테스트 노트에있는 주석) – grey

+0

@grey : 오히려, 나는 그것에 대해 확신하지 못한다. 나는 그것이 스케일링 문제라고 생각 하겠지만, 디버거에서 실행하는 것이 유일한 방법 일 것이다. –

1

프로그램 중간의 인쇄 문이 내 기억에 상처를 입혔습니다. 여기에 작업 정렬이 있습니다. 모두 도움을 주셔서 감사합니다!

.data 
      aa DWORD 10 DUP(5, 7, 6, 1, 4, 3, 9, 2, 10, 8) 
     count DWORD -1 
; DB 8-bits, DW 16-bit, DWORD 32, WORD 16 BYTE 8 



    .code      ; Tell MASM where the code starts 

; ««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««« 

start:       ; The CODE entry point to the program 

    mov esi, count ;loop count 

    outer: 
     inc esi 
     mov edi, count   
     cmp esi, 10  
     je end_loop 

    inner: ;this loop represents a full pass on the entire array 
     inc edi   
     cmp edi, 9 ;after 9 passes goes to outer loop 
     je outer 

    compare: 
     mov eax, [aa + edi * 4h] 
     mov ebx, [aa + edi * 4h + 4] ;want to make this one the higher indexed-one 

     ;print chr$(13,10) These print calls were hosing the memory before. 
     ;print str$(eax) 
     ;print chr$(13, 10) 
     ;print str$(ebx) 
     ;print chr$(13, 10) 

     cmp eax, ebx 
     jle inner 

    swap: 
     mov [aa + edi * 4h], ebx 
     mov [aa + edi * 4h + 4], eax 
     jmp inner 

end_loop: 

    ;print out array elements 
    sub esi, esi 
    mov esi, [aa] 
    print str$(esi) 
    print chr$(" ") 
    sub esi, esi 

    mov esi, [aa + 4h] 
    print str$(esi) 
    print chr$(" ") 
    sub esi, esi 

    mov esi, [aa + 4h * 2] 
    print str$(esi) 
    print chr$(" ") 
    sub esi, esi 

    mov esi, [aa + 4h * 3] 
    print str$(esi) 
    print chr$(" ") 
    sub esi, esi 

    mov esi, [aa + 4h * 4] 
    print str$(esi) 
    print chr$(" ") 
    sub esi, esi 

    mov esi, [aa + 4h * 5] 
    print str$(esi) 
    print chr$(" ") 
    sub esi, esi 

    mov esi, [aa + 4h * 6] 
    print str$(esi) 
    print chr$(" ") 
    sub esi, esi 

    mov esi, [aa + 4h * 7] 
    print str$(esi) 
    print chr$(" ") 
    sub esi, esi 

    mov esi, [aa + 4h * 8] 
    print str$(esi) 
    print chr$(" ") 
    sub esi, esi 

    mov esi, [aa + 4h * 9] 
    print str$(esi) 
    print chr$(" ") 
    sub esi, esi 

exit 


; ««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««« 

end start      ; Tell MASM where the program ends 
+0

이것은 디버그 프린트 함수 호출이나 매크로 대신 디버거를 사용하는 이유입니다! –

+0

이것은 실제로 메모리가있는 느린'xchg' (암시 적'lock' 접두사) 또는 [느린'loop' 명령] (https://stackoverflow.com/)과 같은 바보 같은 것들 없이는 꽤 깨끗한 버블 정렬입니다. 질문/35742570/loop-instruction-slow-couldnt-intel-have-implemented-it-efficient) 또는 기타 낭비적인 지침을 제공합니다. 또한 브랜치/루프 구조는 꽤 깨끗합니다. swap : swap : swap : swap : swap : swap : swap : swap : swap : swap : swap : swap : swap : swap : swap : swap : swap : –

+0

'count'에서'-1'을로드하는 것은 매우 추악합니다. 그렇기 때문에 요소의 수를 하드 코딩합니다. 메모리에서 초기 'count'를로드하지만 '10'을 하드 코딩하면 아무런 의미가 없습니다. :// 바깥 쪽 루프를'do {} while()'으로 구조화하면 바닥에있는 루프 조건이 더 깨끗해집니다. 또한, 끝 부분의 인쇄물은 분명히 * 루프가되어야하지만, 적어도 그것은 정렬 이후에 나오므로 대답은 읽을 수 있습니다. –

관련 문제