FAQ Поиск Пользователи Группы ФотоАльбом  Регистрация Войти и проверить личные сообщения Вход
Как оптимизировать функцию на ассемблере

 
Начать новую тему   Ответить на тему       Список форумов Forum.profintel.ru -> Программерский раздел
Предыдущая тема :: Следующая тема  
Автор Сообщение
assch
Дух


Репутация: 0    

Зарегистрирован: 05.02.2011
Сообщения: 3


СообщениеДобавлено: Сб Фев 05, 2011 4:10 am    Заголовок сообщения: Как оптимизировать функцию на ассемблере Ответить с цитатой

Просто ради интереса собрал функцию на ассемблере которая создаёт список всех файлов,
в данном случае на диске С .Только пока получилось слишком громоздко сам код расчитан что вложенность
файлов будет не больше 20 папок, в большенстве случаев этого хватает (хотя код позволяет увеличить зтот показатель)
Не подскажете как оптимизировать эту функцию другим алгоритмом.
В книге Пирогова Ассемблер для Windows есть функция подобного рода она вроде бы оптимизирована, только для сомообразования
плохо поддаётся для восприятия поскольку не понятно как там сохраняются локальные переменные
А для самообразования хочется именно понять сам алгоритм.
Код:
.386
.model flat, stdcall
option casemap :none   

include \masm32\include\windows.inc
include \masm32\include\user32.inc
include \masm32\include\kernel32.inc

includelib c:\masm32\lib\user32.lib
includelib c:\masm32\lib\kernel32.lib

.data

FIN         WIN32_FIND_DATA <0>
fName       db "info.txt",0
BUF         db "C:",0
           db 300 dup(0)
BUD         db " ",0
           db 300 dup(0)
MASKA       db "*.*"
           db 50 dup(0)
AP          db "\",0
hanf        dd 0
write       dd 0

.code
start:
invoke CreateFile,ADDR fName,GENERIC_READ+GENERIC_WRITE,0,0,2,0,0
mov hanf,eax
call  Find
exit:
invoke ExitProcess,0

Find proc
local var   :DWORD
local hand  :DWORD
local hand1 :DWORD
local hand2 :DWORD
local hand3 :DWORD
local hand4 :DWORD
local hand5 :DWORD
local hand6 :DWORD
local hand7 :DWORD
local hand8 :DWORD
local hand9 :DWORD
local hand10 :DWORD
local hand11 :DWORD
local hand12 :DWORD
local hand13 :DWORD
local hand14 :DWORD
local hand15 :DWORD
local hand16 :DWORD
local hand17 :DWORD
local hand18 :DWORD
local hand19 :DWORD
local hand20 :DWORD

local str1  :DWORD
local str2  :DWORD
local str3  :DWORD
local str4  :DWORD
local str5  :DWORD
local str6  :DWORD
local str7  :DWORD
local str8  :DWORD
local str9  :DWORD
local str10  :DWORD
local str11  :DWORD
local str12  :DWORD
local str13  :DWORD
local str14  :DWORD
local str15  :DWORD
local str16  :DWORD
local str17  :DWORD
local str18  :DWORD
local str19  :DWORD
local str20  :DWORD
mov var,0
mov str1,0
mov str2,0
mov str3,0
mov str4,0
mov str5,0
mov str6,0
mov str7,0
mov str8,0
mov str9,0
mov str10,0
mov str11,0
mov str12,0
mov str13,0
mov str14,0
mov str15,0
mov str16,0
mov str17,0
mov str18,0
mov str19,0
mov str20,0
MetkaFind:
inc var
lea esi,BUF
invoke lstrcat,esi,addr AP
invoke lstrlen,esi
mov edi,eax
invoke lstrcat,esi,addr MASKA
invoke FindFirstFile,esi,addr FIN
mov hand,eax
cmp eax,-1
je Metka0
.if var == 1
mov hand1,eax
mov str1,edi
.endif
.if var == 2
mov hand2,eax
mov str2,edi
.endif
.if var == 3
mov hand3,eax
mov str3,edi
.endif
.if var == 4
mov hand4,eax
mov str4,edi
.endif
.if var == 5
mov hand5,eax
mov str5,edi
.endif
.if var == 6
mov hand6,eax
mov str6,edi
.endif
.if var == 7
mov hand7,eax
mov str7,edi
.endif
.if var == 8
mov hand8,eax
mov str8,edi
.endif
.if var == 9
mov hand9,eax
mov str9,edi
.endif
.if var == 10
mov hand10,eax
mov str10,edi
.endif
.if var == 11
mov hand11,eax
mov str11,edi
.endif
.if var == 12
mov hand12,eax
mov str12,edi
.endif
.if var == 13
mov hand13,eax
mov str13,edi
.endif
.if var == 14
mov hand14,eax
mov str14,edi
.endif
.if var == 15
mov hand15,eax
mov str15,edi
.endif
.if var == 16
mov hand16,eax
mov str16,edi
.endif
.if var == 17
mov hand17,eax
mov str17,edi
.endif
.if var == 18
mov hand18,eax
mov str18,edi
.endif
.if var == 19
mov hand19,eax
mov str19,edi
.endif
.if var == 20
mov hand20,eax
mov str20,edi
.endif
Metka1:
cmp byte ptr FIN.cFileName,"."
je Metka2
Metka3:
mov byte ptr [esi+edi],0
invoke lstrcat,esi,addr FIN.cFileName
test byte ptr FIN.dwFileAttributes,10H
jne Metka4
lea ebx,BUD
lea eax,BUF
invoke lstrcpy,ebx,eax
invoke   lstrlen, ebx
add   ebx, eax
MOV  BYTE PTR [ebx],13
MOV  BYTE PTR [ebx+1],10
sub   ebx, eax
add eax,2
invoke WriteFile,hanf,ebx,eax,addr write,0
jmp Metka0
Metka4:
lea ebx,BUD
lea eax,BUF
invoke lstrcpy,ebx,eax
invoke   lstrlen, ebx
add   ebx, eax
MOV  BYTE PTR [ebx],13
MOV  BYTE PTR [ebx+1],10
sub   ebx, eax
add eax,2
invoke WriteFile,hanf,ebx,eax,addr write,0
jmp MetkaFind
Metka0:

invoke FindNextFile,hand,addr FIN
cmp  eax,0
jne Metka1
invoke FindClose,hand
dec var
.if var == 0
jmp exit
.endif
.if var == 1
mov eax,hand1
mov hand,eax
mov edi,str1
.endif
.if var == 2
mov eax,hand2
mov hand,eax
mov edi,str2
.endif
.if var == 3
mov eax,hand3
mov hand,eax
mov edi,str3
.endif
.if var == 4
mov eax,hand4
mov hand,eax
mov edi,str4
.endif
.if var == 5
mov eax,hand5
mov hand,eax
mov edi,str5
.endif
.if var == 6
mov eax,hand6
mov hand,eax
mov edi,str6
.endif
.if var == 7
mov eax,hand7
mov hand,eax
mov edi,str7
.endif
.if var == 8
mov eax,hand8
mov hand,eax
mov edi,str8
.endif
.if var == 9
mov eax,hand9
mov hand,eax
mov edi,str9
.endif
.if var == 10
mov eax,hand10
mov hand,eax
mov edi,str10
.endif
.if var == 11
mov eax,hand11
mov hand,eax
mov edi,str11
.endif
.if var == 12
mov eax,hand12
mov hand,eax
mov edi,str12
.endif
.if var == 13
mov eax,hand13
mov hand,eax
mov edi,str13
.endif
.if var == 14
mov eax,hand14
mov hand,eax
mov edi,str14
.endif
.if var == 15
mov eax,hand15
mov hand,eax
mov edi,str15
.endif
.if var == 16
mov eax,hand16
mov hand,eax
mov edi,str16
.endif
.if var == 17
mov eax,hand17
mov hand,eax
mov edi,str17
.endif
.if var == 18
mov eax,hand18
mov hand,eax
mov edi,str18
.endif
.if var == 19
mov eax,hand19
mov hand,eax
mov edi,str19
.endif
.if var == 20
mov eax,hand20
mov hand,eax
mov edi,str20
.endif
jmp Metka0
Metka2:
test byte ptr FIN.dwFileAttributes,10H
je Metka3
jne Metka0
Find endp
end start
Вернуться к началу
Посмотреть профиль Отправить личное сообщение
assch
Дух


Репутация: 0    

Зарегистрирован: 05.02.2011
Сообщения: 3


СообщениеДобавлено: Вт Фев 08, 2011 12:45 am    Заголовок сообщения: Ответить с цитатой

Кажется что то пулучилось
Если кому интересно выкладываю код с коментариями

Код:
.386
.model flat, stdcall
option casemap :none   

include \masm32\include\windows.inc
include \masm32\include\user32.inc
include \masm32\include\kernel32.inc

includelib c:\masm32\lib\user32.lib
includelib c:\masm32\lib\kernel32.lib

.data
winfd     WIN32_FIND_DATA <0>   ;объявляем структуру WIN32_FIND_DATA
fname     db "info.txt",0   ;инициализируем переменную fname названием файла "info.txt"
bufer     db "C:",0   ;можно и конкретно указать адрес например "C:\Documents and Settings"
         db 300 dup(0)   ;размер переменной bufer
fhand     dd 0   ;объявляем переменную fhand
write     dd 0   ;объявляем переменную write
chrta     dd 0   ;объявляем переменную chrta
maska     dd 0   ;объявляем переменную maska

.data?
rider     db 300 dup (?)   ;чтобы не отражался на весе экзешника объявим переменную rider в разделе - .data?

.code
start:

invoke CreateFile,addr fname,GENERIC_READ+GENERIC_WRITE,0,0,2,0,0   ;создаём файл "info.txt"
mov fhand,eax   ;записываем хендл в переменную fhand
mov chrta,5ch   ;инициализируем переменную "\"
mov maska,2a2e2ah   ;инициализируем переменную маской "*.*"
call  Find   ;запускаем функцию Find
invoke CloseHandle,fhand   ;закрываем хендл
invoke ExitProcess,0   ;корректно выходим из программы

Find proc   ;начало функции Find
local handl :DWORD   ;объявляем переменную handl
local simvl :DWORD   ;объявляем переменную simvl
lea esi,bufer   ;адрес переменной bufer передаём регистру esi
invoke lstrcat,esi,addr chrta   ;как пример к "C:" добавляем "\" получаем "C:\" в следующих заходах esi будет другая
invoke lstrlen,esi   ;узнаём количество байт заполненных по адресу который курирует регистр esi как пример "C:\" - 3 байта
mov simvl,eax  ;результат записываем в переменную simvl
invoke lstrcat,esi,addr maska   ;как пример к "C:\" добавляем маску "*.*" получаем "C:\*.*" в следующих заходах esi будет другая
invoke FindFirstFile,esi,addr winfd   ;функция ищет первый файл в объявленной директории
mov handl,eax   ;если находит записывает хендл этой директории в переменную handl
cmp eax,-1   ;сравнение значения,если есть файл то значение eax будет не "-1"
je Metka0   ;если eax "-1" то переход на метку Metka0
Metka1:   ;метка
cmp byte ptr winfd.cFileName,2eh   ;сравнение
je Metka2   ;если в названии файла первый байт -  2eh - "." (точка) то переход на метку Metka2
Metka3:   ;метка
mov eax,simvl   ;значение переменной simvl записываем в eax
mov byte ptr [esi+eax],0   ;к значению адреса esi прибавляем значение eax (количество байт) и ставим 0 (байты после нуля уже не видимы)
invoke lstrcat,esi,addr winfd.cFileName   ;дописываем к значению esi название файла
lea ebx,rider   ;адрес переменной rider передаём регистру ebx
lea eax,bufer   ;адрес переменной bufer передаём регистру eax
invoke lstrcpy,ebx,eax   ;записываем значение eax в ebx
invoke   lstrlen, ebx   ;узнаём количество байт заполненных по адресу который курирует регистр ebx
add   ebx, eax   ;перематываем адрес на конец строки (адрес будет сразу же после последнего символа)
mov byte ptr [ebx],0dh   ;прописывам по этому адресу "0dh" - ASCII  LF  (переход на новую строку)
mov byte ptr [ebx+1],0ah   ;сдвигаем адрес на один байт и прописывам "0ah" - ASCII  CR  (конец строки)
sub   ebx, eax   ;отматываем обратно на начало строки
add eax,2   ;прибавляем к прежнему значению eax ещё два байта ("0dh" и "0ah")
invoke WriteFile,fhand,ebx,eax,addr write,0   ;строчку записываем в файл "info.txt"
test byte ptr winfd.dwFileAttributes,10h   ;смотрим есть ли в файле атрибут 10h (атрибут указавает что это директория то есть папка)
jne Metka4   ;если есть атрибут 10h то переход на метку Metka4
jmp Metka0   ;безусловный переход на метку Metka0
Metka4:   ;метка
call  Find   ;рекурсия (функция вызывает сама себя)
Metka0:   ;метка
invoke FindNextFile,handl,addr winfd   ;функция ищет следующий файл в данной директории
cmp  eax,0   ;сравнение ,не равно ли eax - "0" (если ноль то файлов нет и тогда перепрыгиваем через следующую строчку кода "jne Metka1")
jne Metka1   ;если находит следующий файл то переход на метку Metka1
invoke FindClose,handl   ;закрытие хендла данной директории
ret   ;возвращаемся из функции
Metka2:   ;метка
test byte ptr winfd.dwFileAttributes,10h   ;ещё одно условие для сравнения для файлов с точкой в начале на наличие в файле атрибута "10h"
je Metka3   ;если нет атрибута "10h" (директория) значит это файл и тогда переход на метку Metka3
jne Metka0   ;если есть атрибут "10h" (директория) то переход на метку Metka0
Find endp   ;конец функции Find

end start
Вернуться к началу
Посмотреть профиль Отправить личное сообщение
Показать сообщения:   
Начать новую тему   Ответить на тему       Список форумов Forum.profintel.ru -> Программерский раздел Часовой пояс: GMT + 6
Страница 1 из 1

 
Перейти:  
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете вкладывать файлы
Вы не можете скачивать файлы