Trix Napisano Październik 28, 2019 Autor Zgłoś Udostępnij Napisano Październik 28, 2019 Witam Moj problem polega na tym ze, gdy po odczycie daty ostatniego wpisu w pliku i jej konwersji na czas systemowy konwertuje ja na ciag znakow funkcja wsprintf to niestety wynikiem sa jakies liczby ktore z pewnoscia nie sa data ani czasem. Oto fragment kodu: invoke FileTimeToSystemTime, ADDR FoundData.ftLastWriteTime, ADDR STime .if eax == 0 invoke MessageBox, NULL, SADD("Blad przy konwersji daty"), SADD("Konwersja daty"), MB_OK .endif invoke wsprintf, ADDR fsBuf, ADDR templateData, STime.wHour, STime.wMinute, STime.wDay, STime.wMonth, STime.wYear Ponizej zmienne wykorzystywane we fragmencie: LOCAL FoundData: WIN32_FIND_DATA LOCAL STime: SYSTEMTIME LOCAL fsBuf[MAX_PATH]: BYTE ; pomocniczy bufor templateData db "%u:%u %u-%u-%u",0 ciag formatujacy Wczesniej w programie struktura FoundData jest oczywiscie wypelniana przez funkcje FindNextFile. W czym moze byc problem? Cytuj Link do komentarza Udostępnij na innych stronach More sharing options...
Surprise Napisano Październik 28, 2019 Zgłoś Udostępnij Napisano Październik 28, 2019 Ja tam zawsze daty przekzuje jako %d, a może coś z ciągiem formatującym nie tak, może przekaż go bezpośrednio...nie wiem ;) pozdrawiam Cytuj Link do komentarza Udostępnij na innych stronach More sharing options...
Trix Napisano Październik 28, 2019 Autor Zgłoś Udostępnij Napisano Październik 28, 2019 Witam Zdaje sie, ze juz mniej wiecej wiem gdzie siedzi problem - prawdopodobnie jest nim funkcja wsprintf! Po deasemblacji programu zauwazylem ze na stos wrzucany jest tylko pierwszy parametr, a nastepne nie sa juz wrzucane parametry tylko zamiast nich sa instrukcje push 0 . Nie wiem dokladnie co tam sie dzieje bo nie mam czasu tego analizowac ale z ta funkcja wsprintf sa same problemy...Moj problem rozwiazalem srednio fajnie ale wazne ze dziala - zamiast wrzucac wszystko do wsprintf dopisuje poprostu do bufora kolejne przekonwertowane liczby. Wyglada to tak: invoke FileTimeToLocalFileTime, ADDR FoundData.ftLastWriteTime, ADDR FTime invoke FileTimeToSystemTime, ADDR FTime, ADDR STime invoke wsprintf, ADDR fsBuf, SADD("%u:"), STime.wHour invoke wsprintf, ADDR temp, SADD("%02u "), STime.wMinute invoke lstrcat, ADDR fsBuf, ADDR temp invoke wsprintf, ADDR temp, SADD("%u-"), STime.wDay invoke lstrcat, ADDR fsBuf, ADDR temp invoke wsprintf, ADDR temp, SADD("%02u-"), STime.wMonth invoke lstrcat, ADDR fsBuf, ADDR temp invoke wsprintf, ADDR temp, SADD("%u"), STime.wYear invoke lstrcat, ADDR fsBuf, ADDR temp Byc moze zle tez tworzylem ciag formatujacy ale probowalem z wieloma typami i nic to nie dawalo wiec watpie. Oczywiscie wsprintf z jednym paramterem dziala poprawnie. pozdrawiam Cytuj Link do komentarza Udostępnij na innych stronach More sharing options...
Burn Napisano Październik 28, 2019 Zgłoś Udostępnij Napisano Październik 28, 2019 Witam Problem nie tkwi w samej funkcji wsprintf a w sposobie przekazywania parametrów. Kompilator spodziewa się argumentu 32 bitowego (dword) a otrzymuje 16 bitowy (word). Dlatego uzupełnia to sobie w niezbyt mądry sposób przez dodanie push 0 pomiędzy argumentami. Aby pozbyć się prolemu można napisać tak: sub eax, eax ;lepiej wyzerować rejestr mov ax, STime.wYear ;zapisz word do rejeestru ax push eax ;teraz idzie dword na stos jak oczekuje kompilator mov ax, STime.wMonth push eax mov ax, STime.wDay push eax mov ax, STime.wMinute push eax mov ax, STime.wHour push eax lea eax, templateData push eax lea eax, fsBuf push eax call wsprintf Myślę ,że to lepsze od Twojego obejścia problemu a taksamo działa :P Pozdro Cytuj Link do komentarza Udostępnij na innych stronach More sharing options...
Trix Napisano Październik 30, 2019 Autor Zgłoś Udostępnij Napisano Październik 30, 2019 Faktycznie! Teraz kiedy to wyjasiles wydaje sie to prawie oczywiste:). Dzieki wielkie! Troche bez sensu jest to ze kompilator wlasnie tak rozwija invoke'a...Z tego co wycztalem z dokumentacji funkcji to proces wywolujacy jest odpowiedzialny za oczyszczenie stosu - zatem trzeba po instrukcji call dodac jeszcze add ESP, 28... Zastanawia mnie tylko jeszcze jedna rzecz: gdy program wrzuca na stos zmienna typu np. WORD to i tak na stos wrzucana jest warotsc DWORD ( ponoc wynika to z tego ze jest to szybsze) - czyli jest jakby wyrownanie do DWORD. Dlaczego wiec nie wrzuca poprawnie tego? Czy moze sie myle? ps. Fajnie ze piszesz w asmie bo ciezko jest sie kogos poradzic, gdy kroluje c++:) Cytuj Link do komentarza Udostępnij na innych stronach More sharing options...
Burn Napisano Październik 30, 2019 Zgłoś Udostępnij Napisano Październik 30, 2019 Witam Cieszę się, że się przydało :D Niestety nie wiem, dlaczego źle interpretuje akurat to. Zrobiłem nawet sobie z ciekawości przykładową funkcję gdzie parametrami były kolejno 2 byte, 2 word, 2 dword i wszystko Ok (na stos rzeczywiście jest wrzucony dword przynajmniej tak pokazuje dissasembler). Być może wina leży w tym, że wsprintf ma nie określoną liczbę argumentów. Pozdro Cytuj Link do komentarza Udostępnij na innych stronach More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.