Ну для примера: 1) скажем есть уже файл f1.txt, в нём записаны буквы "аабб" 2) открываем файл f1 и читаем из него символы 3) к аски коду каждого символа прибавляем 1h (буква меняется на следующую в алфавите) (E0+1h = б, E1+1h = в...) 4)создаём новый файл f2.txt 5)пишем туда результат (если вначале было "аабб", то сейчас "ббвв") програ позарез сегодня нужна, кто сделает, тому большой респект. Спасибо П.С. если это возможно, то не моглибы (use 64) но впринципе и на 32 тоже подойдёт.
newb Не могу написать или не хочу подумать и разобраться? Вот что у меня получилось. Тут в общем-то одни API вызовы и все. Ничего сложного. Code (Text): format PE GUI 4.0 entry WINMAIN include '%fasminc%\win32a.inc' section '.data' data readable writeable fin db 'f1.txt',0 fout db 'f2.txt',0 hFile dd ? lFile dd ? inbuf dd ? hFileO dd ? szFileWritten dd ? szReadByte dd ? section '.code' code readable executable proc WINMAIN hInst, hprevinstance, lpcmdline, ncmdshow invoke CreateFile,\ fin,\ GENERIC_READ,\ 0,\ NULL,\ OPEN_EXISTING,\ FILE_ATTRIBUTE_ARCHIVE,\ NULL mov [hFile],eax invoke GetFileSize,[hFile],NULL mov [lFile],eax invoke CreateFile,\ fout,\ GENERIC_READ or GENERIC_WRITE,\ FILE_SHARE_READ or FILE_SHARE_WRITE,\ NULL,\ CREATE_NEW,\ FILE_ATTRIBUTE_ARCHIVE,\ NULL mov [hFileO],eax xor ecx,ecx add ecx,[lFile] @loop: push ecx invoke ReadFile,[hFile],inbuf,1,szReadByte,NULL add [inbuf],1 invoke WriteFile,[hFileO],inbuf,1,szFileWritten,NULL pop ecx dec ecx jnz @loop invoke CloseHandle,[hFile] invoke CloseHandle,[hFileO] invoke ExitProcess, 0 endp section '.idata' import data readable writeable library kernel32,'KERNEL32.DLL',\ user32,'USER32.DLL' include '%fasminc%/apia/kernel32.inc' include '%fasminc%/apia/user32.inc'
Code (Text): xor ecx,ecx add ecx,[lFile] ; Вместо обоих инстр-ий - mov ecx,[hFile] ;--- dec ecx jnz @loop ; Вместо обоих инстр-ий - loop @loop
Code (Text): xor ecx,ecx add ecx,[lFile] ; Вместо обоих инстр-ий - mov ecx,[hFile] ;--- dec ecx jnz @loop ; Вместо обоих инстр-ий - loop @loop
Code (Text): format PE GUI 4.0 entry WINMAIN include '%fasminc%\win32a.inc' null equ ebx section '.data' data readable writeable fin db 'f1.txt',0 fout db 'f2.txt',0 hFile dd ? lFile dd ? inbuf dd ? hFileO dd ? szFileWritten dd ? szReadByte dd ? section '.code' code readable executable proc WINMAIN uses ebx esi xor ebx, ebx invoke CreateFile,\ fin,\ GENERIC_READ,\ null,\ null,\ OPEN_EXISTING,\ FILE_ATTRIBUTE_ARCHIVE,\ null mov [hFile],eax invoke GetFileSize,[hFile],null mov [lFile],eax invoke CreateFile,\ fout,\ GENERIC_READ or GENERIC_WRITE,\ FILE_SHARE_READ or FILE_SHARE_WRITE,\ null,\ CREATE_NEW,\ FILE_ATTRIBUTE_ARCHIVE,\ null mov [hFileO],eax mov esi,[lFile] @loop: invoke ReadFile,[hFile],inbuf,1,szReadByte,null inc [inbuf] invoke WriteFile,[hFileO],inbuf,1,szFileWritten,null dec esi jnz @loop invoke CloseHandle,[hFile] invoke CloseHandle,[hFileO] pop esi pop ebx invoke ExitProcess, null endp section '.idata' import data readable writeable library kernel32,'KERNEL32.DLL',\ user32,'USER32.DLL' include '%fasminc%/api/kernel32.inc' include '%fasminc%/api/user32.inc'
2FED loop может и тормознутная, да с чем сравнивать. В данном цикле вызываются ReadFile, WriteFile и сколько же сотых долей % времени будет тратить loop? А ebx тут делает короче инструкции push, в нем константа. ИМХО ebx не обязан сохраняться (http://www.wasm.ru/article.php?article=1005012), видимо надо использовать edi. И не надо под переменные в секции данных резервировать место, можно использовать стек через ebp (только не sub esp,xxx, а по получении очередного HANDLE - push eax), кроме того сохранение esi, ebx не требуется в начале, кому они будут нужны?
ADim почему тогда записано push null а не push ebx? esi,edi и ebx надо сохранять, апи их вроде и не используют а вот у меня бывало так что программа падала изза того что не сохранил. и БСОДЫ бывали когда в драйверах не сохранях их значений. так что лучше перестраховатся
Надеюсь так всех устроит Code (Text): format PE GUI 4.0 entry main include '%fasminc%\win32ax.inc' null equ ebx section '.data' data readable fin db 'f1.txt',0 fout db 'f2.txt',0 section '.code' code readable executable proc main locals hFile dd ? lFile dd ? inbuf dd ? hFileO dd ? szFileWritten dd ? szReadByte dd ? endl xor ebx, ebx ; Init null invoke CreateFile,\ fin,\ GENERIC_READ,\ null,\ null,\ OPEN_EXISTING,\ FILE_ATTRIBUTE_ARCHIVE,\ null mov [hFile],eax invoke GetFileSize,[hFile],null mov [lFile],eax invoke CreateFile,\ fout,\ GENERIC_READ or GENERIC_WRITE,\ FILE_SHARE_READ or FILE_SHARE_WRITE,\ null,\ CREATE_NEW,\ FILE_ATTRIBUTE_ARCHIVE,\ null mov [hFileO],eax mov esi,[lFile] @loop: invoke ReadFile,[hFile],addr inbuf,1,addr szReadByte,null inc [inbuf] invoke WriteFile,[hFileO],addr inbuf,1,addr szFileWritten,null dec esi jnz @loop invoke CloseHandle,[hFile] invoke CloseHandle,[hFileO] invoke ExitProcess, null endp section '.idata' import data readable writeable library kernel32,'KERNEL32.DLL',\ user32,'USER32.DLL' include '%fasminc%/api/kernel32.inc' include '%fasminc%/api/user32.inc'
Если количество итераций в цикле не велико, то LOOP займёт меньше кода. Но если итераций много, то конечно DEC/JNZ быстрее. Как-то давно я переводил один парсер из С в ассемблер. Ну там, обычное дело - грузим файл целиком в память и побайтно вперёд! Замерил скорость - сишный вариант (в релизе) скорее на где-то 25% - что за дела?! Стал смотреть сишный код в дизассемблере - и естественно, вместо LOOP (который я поставил в ассемблере) компилятор VC++ поставил пару DEC/JNZ. Заменил, замерил снова - всё примерно сравнялось по времени.
zet Человека, создавшего пост, должно устроить и так и сяк, ему же надо бы только ReadFile/WriteFile, видимо, что-то вроде лабораторной работы? А касательно LOCALS: повлечет за собой (считайте байты кода): push ebp, mov ebp,esp, sub esp,xxx и в эпологе что-то наподобие: mov esp,ebp, pop ebp. Это раз. Для каждой инициализации переменных: hFile, hFileO, lFile требуется mov [ebp-xxx],eax. Это два. Если же не использовать LOCALS, а по получении возвращаемых значений CreateFile, GetFileSize заталкивать в стек, тогда: 1) пролог - push ebp mov ebp,esp без sub esp,xxx 2) эпилог - pop ebp без mov esp,ebp 3) инициализация переменных - push eax (1 байт) против 3-х mov [ebp-xxx],eax. Только для данного случая сохранять и восстанавливать ebp не нужно, процедура-то оканчивается ExitProcess. Доступ к таким переменным ничем не отличается от вашего подхода, только теперь придется считать отрицательное смещение, компилятор за Вас этого более делать не будет. Счетчик цикла можно в esi не заносить, т.к. либо он будет сидеть в кэше и тогда доступ будет осуществляться быстро, либо очень "медленно", но это означает, что др. процессы заняли столько времени, что им даже удалось очистить кэш. Ну, и 0-й размер файла тоже не проверяется. Для пролога fasm использует enter? Полный оффтоп...
Ой, забыл, забыл! Если последовательно заталкивать в стек HANDLE файлов после CreateFile, то и для CloseHandle не потребуется в стек помещать их снова, они уже там.
ADim AsmGuru62 Как это тут можно вообще говорить о скорости, loop по сравнению с ReadFile капля в море D