Moze ktos pomóc mam program napisany w jezyku asemblera jego zadaniem jest sortowanie liczb całkowitych, po nacisnieciu przycisku, program czyta liczby z pliku i zapisuje je juz posortowane, problem tkwi w tym ze zawiesza sie, i nie wypisuje danych juz posortowanych do konsoli. Moze ktos to ogarnie.
.586P
.MODEL flat, STDCALL
;--- struktury ---
LARGE_INTEGER UNION
STRUCT
LowPart DWORD ?
HighPart DWORD ?
ENDS
QuadPart QWORD ?
LARGE_INTEGER ENDS
;--- funkcje API Win32 ---
;--- funkcje
GetTickCount PROTO
;;DWORD GetTickCount(VOID) ;czas w milisekundach od uruchomienia komputera
QueryPerformanceFrequency PROTO lpFrequency:DWORD
;;BOOL QueryPerformanceFrequency(
;;LARGE_INTEGER *lpFrequency // address of current frequency );
QueryPerformanceCounter PROTO lpPerformanceCount:DWORD
;;BOOL QueryPerformanceCounter(
;;LARGE_INTEGER
;--- pliki ---------
include .\include\grafika.inc
;--- biblioteki ---------
includelib .\lib\user32.lib
includelib .\lib\kernel32.lib
includelib .\lib\gdi32.lib
INCLUDELIB .\lib\masm32.lib
STD_INPUT_HANDLE equ -10
STD_OUTPUT_HANDLE equ -11
GENERIC_READ equ 80000000h
GENERIC_WRITE equ 40000000h
CREATE_NEW equ 1
CREATE_ALWAYS equ 2
OPEN_EXISTING equ 3
OPEN_ALWAYS equ 4
;---stale pomiaru czasu---
STD_INPUT_HANDLE equ -10
STD_OUTPUT_HANDLE equ -11
;--- funkcje API Win32 z pliku .\include\user32.inc ---
CharToOemA PROTO :DWORD,:DWORD
GetStdHandle PROTO :DWORD
ReadConsoleA PROTO :DWORD,:DWORD,:DWORD,:DWORD,:DWORD
WriteConsoleA PROTO :DWORD,:DWORD,:DWORD,:DWORD,:DWORD
ExitProcess PROTO :DWORD
lstrlenA PROTO :DWORD
GetTickCount PROTO
GetStdHandle PROTO :DWORD
ReadConsoleA PROTO :DWORD,:DWORD,:DWORD,:DWORD,:DWORD
WriteConsoleA PROTO :DWORD,:DWORD,:DWORD,:DWORD,:DWORD
ExitProcess PROTO :DWORD
lstrlenA PROTO :DWORD
GetCurrentDirectoryA PROTO :DWORD,:DWORD
CreateDirectoryA PROTO :DWORD,:DWORD
lstrcatA PROTO :DWORD,:DWORD
CreateFileA PROTO :DWORD,:DWORD,:DWORD,:DWORD,:DWORD,:DWORD,:DWORD
lstrcpyA PROTO :DWORD,:DWORD
CloseHandle PROTO :DWORD
WriteFile PROTO :DWORD,:DWORD,:DWORD,:DWORD,:DWORD
ReadFile PROTO :DWORD,:DWORD,:DWORD,:DWORD,:DWORD
CopyFileA PROTO :DWORD,:DWORD,:DWORD
GetLastError PROTO
GetFileSize PROTO :DWORD, :DWORD
;--- stałe ---
CSstyle EQU CS_HREDRAW+CS_VREDRAW+CS_GLOBALCLASS
BSstyle EQU BS_PUSHBUTTON+WS_VISIBLE+WS_CHILD+WS_TABSTOP
WNDstyle EQU WS_CLIPCHILDREN OR WS_OVERLAPPEDWINDOW OR \
WS_HSCROLL OR WS_VSCROLL
STATstyle EQU SS_CENTER+WS_VISIBLE+WS_CHILD+WS_TABSTOP+WS_BORDER
kolor EQU 000000FFh ; czerwony ; kolory: G B R
;--- sekcja danych ------
_DATA SEGMENT
hwnd DD 0
hinst DD 0
hdc DD 0
hbutt DD 0
hedt DD 0
hbrush DD 0
holdbrush DD 0
hout DD 0
rout DD 0
hinp DD 0
rinp DD 0
nl DB 0Dh,0Ah,0
;----zmienne dotyczace obliczenia czasu------
wzor DB 0Dh,0Ah,"Czas = %ld periodow przy czestotliwosci %ld periodow/sek", 0
czas1 DD ?
delta DD ?
czest DD ?
;-----zmienne do pliku-----------------------
newDirName DB "\dane",0
newDirNameSize DD $ - newDirName
plik DB "\dane_wejsciowe.txt",0
file1Path DB 128 dup(?)
file1IO DD ?
plik2 DB "\Posortowane_liczby_calkowite.txt",0
file2Path DB 128 dup(?)
file2IO DD ?
plik3 DB "\czas_wykonania_algorytmu.txt",0
file3Path DB 128 dup(?)
file3IO DD ?
output DB "%ld",0Dh,0Ah,0
consoleOut DD ?
sth DB 0
dir DB 128 dup(?)
dirSize DD 128
buforSize DD 128
temp DB "%d ",0
hfile DD 0
rfile DD 0
liczba DB 1024 dup(?)
;-----zmienne do sortowania-----------------------
tab1 DD 5000 dup(0)
liczbaTmp DD 1
iloscLiczb DD 1
i DD 1
j DD 1
n1 DD 1
n2 DD 1
tmp DD 1
;-----zmienne dodatkowe----------------------------
naglow DB "Autor programu: Ja.",0
rozmN DD $ - naglow ;ilość znaków w tablicy
naglow4 DB "Temat: Sortowanie liczb całkowitych w tablicy metodą bombelkową.",0
rozmN4 DD $ - naglow ;ilość znaków w tablicy
puste DB "_____________________" ; spacje
rozmP DD $ - puste ;ilość znaków w tablicy
tytul DB "Projekt z programowania niskopoziomowego.",0
cname DB "MainClass", 0
MES1 DB "Lewy, myszy",0
tbutt DB "BUTTON", 0
tstart DB "SORTUJ", 0
nagl DB "Komunikat", 0
terr DB "Błąd!", 0
terr2 DB "Błąd 2!", 0
bufor DB 128 dup(' ') ; bufor ze spacjami
rbuf DD 128 ; rozmiar buforu
;-----------------------------------------------------------------
msg MSGSTRUCT <?>
wndc WNDCLASS <?>
;-----------------------------------------------------------------
_BSS SEGMENT
count1 LARGE_INTEGER <>
count2 LARGE_INTEGER <>
freq LARGE_INTEGER <>
_BSS ENDS
_DATA ENDS
;--- sekcja kodu ---------
_TEXT SEGMENT
ScanInt PROC
;; funkcja ScanInt przekształca cišg cyfr do liczby, którš jest zwracana przez EAX
;; argument - zakończony zerem wiersz z cyframi
;; rejestry: EBX - adres wiersza, EDX - znak liczby, ESI - indeks cyfry w wierszu, EDI - tymczasowy
;--- poczštek funkcji
push EBP
mov EBP, ESP ; wska?nik stosu ESP przypisujemy do EBP
;--- odkładanie na stos
push EBX
push ECX
push EDX
push ESI
push EDI
;--- przygotowywanie cyklu
mov EBX, [EBP+8]
push EBX
call lstrlenA
mov EDI, EAX ;ilosć znaków
mov ECX, EAX ;ilosć powtórzeń = ilosć znaków
xor ESI, ESI ; wyzerowanie ESI
xor EDX, EDX ; wyzerowanie EDX
xor EAX, EAX ; wyzerowanie EAX
;--- cykl --------------------------
@@pocz:
cmp BYTE PTR [EBX+ESI], 02Dh ;porównanie z kodem -
jne @@et1
mov EDX, 1
jmp @@nast
@@et1:
cmp BYTE PTR [EBX+ESI], 030h ;porównanie z kodem 0
jae @@et2
jmp @@nast
@@et2:
cmp BYTE PTR [EBX+ESI], 039h ;porównanie z kodem 9
jbe @@et3
jmp @@nast
;----
@@et3:
push EDX ; do EDX procesor może zapisać wynik mnożenia
mov EDI, 10
mul EDI ;mnożenie EAX * EDI
mov EDI, EAX ; tymczasowo z EAX do EDI
xor EAX, EAX ;zerowani EAX
mov AL, BYTE PTR [EBX+ESI]
sub AL, 030h ; korekta: cyfra = kod znaku - kod 0
add EAX, EDI ; dodanie cyfry
pop EDX
@@nast: inc ESI
loop @@pocz
;--- wynik
or EDX, EDX ;analiza znacznika EDX
jz @@et4
neg EAX
@@et4:
;--- zdejmowanie ze stosu
pop EDI
pop ESI
pop EDX
pop ECX
pop EBX
;--- powrót
pop EBP
ret
ScanInt ENDP
WndProc PROC
push EBP ; standardowy prolog
mov EBP, ESP ; standardowy prolog
;--- odkładanie na stos
push EBX
push ESI
push EDI
cmp DWORD PTR [EBP+0Ch], WM_CREATE
jne @F
jmp wmCREATE
@@:
cmp DWORD PTR [EBP+0Ch], WM_DESTROY
jne @F
jmp wmDESTROY
@@:
cmp DWORD PTR [EBP+0CH], WM_COMMAND
jne @F
jmp wmCOMMAND
@@:
;--- komunikaty nieobsługiwane ---
INVOKE DefWindowProcA, DWORD PTR [EBP+08h], \
DWORD PTR [EBP+0Ch], DWORD PTR [EBP+10h], \
DWORD PTR [EBP+14h]
jmp konWNDPROC
wmCREATE:
;--- utworzenie klawisza ---
INVOKE CreateWindowExA, 0, OFFSET tbutt, OFFSET tstart, \
BSstyle, 140, 100, 120, 80, DWORD PTR [EBP+08h], 0, hinst, 0
mov hbutt, EAX
INVOKE SetFocus,hedt
;----------------------------------------------------
INVOKE CreateSolidBrush,kolor
mov hbrush,EAX
;----------------------------------------------
mov EAX,0
jmp konWNDPROC
wmDESTROY:
INVOKE DeleteObject, hbrush
INVOKE PostQuitMessage, 0 ; wysyłanie WM_QUIT
mov EAX, 0
jmp konWNDPROC
wmCOMMAND:
mov EAX,hbutt
cmp EAX,DWORD PTR [EBP+14h] ;czy LPARAM komunikatu \WM_COMMAND = hbutt?
je @F
jmp konWNDPROC
@@:
;------ Otwieranie pliku ------
invoke GetCurrentDirectoryA,rbuf,OFFSET bufor ; Pobiera bierzący katalog do bufora
invoke lstrcatA,OFFSET bufor,OFFSET plik ; Łączy bierzący katalog z nazwą czytanego pliku
invoke CreateFileA,OFFSET bufor,GENERIC_READ,0,0,OPEN_EXISTING,0,0 ; otwiera plik
mov hfile,EAX
mov j,0
mov iloscLiczb,0
@petla1:
cmp bufor,0
je @koniec1
mov EDX,OFFSET bufor
mov DWORD PTR [EDX],0
invoke ReadFile,hfile,OFFSET bufor,1,OFFSET rfile,0
cmp bufor,0Dh
je @koniec2
cmp bufor,0Ah
je @koniec3
invoke lstrcatA,OFFSET liczba,OFFSET bufor
jmp @koniec2
@koniec3:
push OFFSET liczba
call ScanInt
mov ECX,j
mov EDX,OFFSET tab1
mov DWORD PTR [EDX+ECX],EAX
add j,4
; inc j
; inc j
; inc j
; inc j
inc iloscLiczb
@koniec4:
mov EDX,OFFSET liczba
mov DWORD PTR [EDX],0
@koniec2:
jmp @petla1
@koniec1:
mov EAX,iloscLiczb
sub EAX,1
mov iloscLiczb,EAX
;------ Zamknięcie pliku ------
invoke CloseHandle,hfile
;-------------------------------------------------------------
;------KONIEC WCZYTYWANIA LICZB DO TABLICY--------------------
;-------------------------------------------------------------
;-------------------------------------------------------------
;------Poczatek SORTOWANIA------------------------------------
;-------------------------------------------------------------
;-------przygotowanie koncowych wartosci petli---------
mov EAX,iloscLiczb
mov n2,EAX
sub EAX,1
mov n1,EAX
;----------POMIAR CZASU-------------------------------
invoke QueryPerformanceFrequency,OFFSET freq
mov eax, freq.LowPart
mov czest, eax
invoke QueryPerformanceCounter,OFFSET count1
;----sortowanie tablicy----------------------------
mov i,0
petlaI:
mov EAX,iloscLiczb
sub EAX,1
mov j,EAX
petlaJ:
mov EAX,4
imul j
mov EBX,EAX ; indeks j-tego elementu w tablicy
mov EAX,j
sub EAX,1
mov ECX ,4
imul ECX
mov ECX,EAX ; indekst j-1 elementu w tablicy
mov EAX,[tab1+EBX]
mov tmp,EAX ; j
mov EAX,[tab1+ECX] ;j-1
cmp tmp,EAX
jb zamiana
jmp zmniejszJ
zamiana:
mov EAX,[tab1+EBX]
mov tmp,EAX
mov EAX,[tab1+ECX]
mov [tab1+EBX],EAX
mov EAX,tmp
mov [tab1+ECX],EAX
zmniejszJ:
mov EAX,j
sub EAX,1
mov j,EAX
mov EAX,i
cmp j,EAX
ja petlaJ
zwiekszI:
inc i
mov EAX,iloscLiczb
sub EAX,1
cmp i,EAX
jb petlaI
;=------------KONIEC SOTROWANIA-----------------------------------
;---- koniec pomiaru czasu----
invoke QueryPerformanceCounter,OFFSET count2
mov eax, count2.LowPart ; Załaduj do EAX wartość pomiaru czasu po sortowaniu
sub eax, count1.LowPart ; Odejmij od EAX wartość pomiaru czasu przed sortowaniem
mov delta, EAX
;------ pobieranie adresu katalogu------------------------
invoke GetCurrentDirectoryA, dirSize,offset dir
;-------przygotowywanie adresu do pliku sortowanie.txt------
invoke lstrcpyA, offset file3Path, offset dir
invoke lstrcatA, offset file3Path, offset plik3
;-------tworzenie nowego pliku:---------------------------
invoke CreateFileA, offset file3Path, GENERIC_WRITE, 0, 0, CREATE_ALWAYS, 0, 0
mov file3IO, EAX
invoke wsprintfA, offset bufor, offset wzor,delta,czest
mov buforSize, EAX
invoke WriteFile, file3IO, offset bufor, buforSize, offset sth,0
invoke CloseHandle,hfile
;------ pobieranie adresu katalogu------------------------
invoke GetCurrentDirectoryA, dirSize,offset dir
;-------przygotowywanie adresu do pliku sortowanie--------
invoke lstrcpyA, offset file2Path, offset dir
invoke lstrcatA, offset file2Path, offset plik2
;-------tworzenie nowego pliku:---------------------------
invoke CreateFileA, offset file2Path, GENERIC_WRITE, 0, 0, CREATE_ALWAYS, 0, 0
mov file2IO, EAX
;--------wypisanie posortowanej tablicy na ekran i do pliku ----------------
mov i,0
wypisz1:
mov EAX,4
imul i
mov ECX,EAX
mov EDX,OFFSET tab1
mov EAX,DWORD PTR [EDX+ECX]
mov liczbaTmp,EAX
invoke wsprintfA, offset bufor, offset output,liczbaTmp
mov buforSize, EAX
invoke WriteFile, file2IO, offset bufor, buforSize, offset sth,0
inc i
mov EAX,iloscLiczb
cmp i,EAX
jb wypisz1
invoke CloseHandle,hfile
konWNDPROC:
pop EDI
pop ESI
pop EBX
pop EBP ; standardowy epilog
ret 16 ; zwolnienie komórek stosu
WndProc ENDP
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;--- start programu ---
Start:
;--- deskryptor aplikacji ----
INVOKE GetModuleHandleA, 0
mov hinst, EAX
;--- wypełnienie struktury okna WNDCLASS
mov EAX, hinst
mov [wndc.clsHInstance], EAX
mov [wndc.clsStyle], CSstyle
mov [wndc.clsLpfnWndProc], OFFSET WndProc
mov [wndc.clsCbClsExtra], 0
mov [wndc.clsCbWndExtra], 0
INVOKE LoadIconA, 0, IDI_APPLICATION ; ikona
mov [wndc.clsHIcon], EAX
INVOKE LoadCursorA, 0, IDC_ARROW ; kursor
mov [wndc.clsHCursor], EAX
INVOKE GetStockObject, WHITE_BRUSH ; tło
mov [wndc.clsHbrBackground], EAX
mov [wndc.clsLpszMenuName], 0
mov DWORD PTR [wndc.clsLpszClassName], OFFSET cname
;--- rejestracja okna ---
INVOKE RegisterClassA, OFFSET wndc
cmp EAX, 0
jne @F
jmp err0
@@:
;--- utworzenie okna głównego ---
INVOKE CreateWindowExA, 0, OFFSET cname, OFFSET tytul, \
WNDstyle, 40, 30, 500, 280, 0, 0, hinst, 0
cmp EAX, 0
jne @F
jmp err2
@@:
mov hwnd, EAX
INVOKE ShowWindow, hwnd, SW_SHOWNORMAL
INVOKE GetDC,hwnd
mov hdc,EAX
;naglowek
INVOKE lstrlenA,OFFSET naglow
mov rozmN,EAX
INVOKE TextOutA,hDC,120,20,OFFSET naglow,rozmN
INVOKE UpdateWindow, hwnd
;naglowek4
INVOKE lstrlenA,OFFSET naglow4
mov rozmN4,EAX
INVOKE TextOutA,hDC,10,40,OFFSET naglow4,rozmN4
INVOKE UpdateWindow, hwnd
;--- pętla obsługi komunikatów
msgloop:
INVOKE GetMessageA, OFFSET msg, 0, 0, 0
cmp EAX, 0
jne @F
jmp etkon
@@:
cmp EAX, -1
jne @F
jmp err0
@@:
INVOKE TranslateMessage, OFFSET msg
INVOKE DispatchMessageA, OFFSET msg
jmp msgloop
;--- obsługa błędów ---------
err0:
;--- okno z komunikatem o błędzie----
INVOKE MessageBoxA,0,OFFSET terr,OFFSET nagl,0
jmp etkon
err2:
;--- okno z komunikatem o błędzie----
INVOKE MessageBoxA,0,OFFSET terr2,OFFSET nagl,0
jmp etkon
;--- zakończenie procesu ---------
etkon:
INVOKE ExitProcess, [msg.msWPARAM]
_TEXT ENDS
END Start