Ассемблер для Windows



         

Пример простой программы которая осуществляет поиск файлов и выводит их название на экран - часть 3


; сегмент кода _TEXT SEGMENT DWORD PUBLIC USE32 'CODE' START: ; получить HANDLE вывода PUSH STD_OUTPUT_HANDLE CALL GetStdHandle@4 MOV HANDL,EAX ; получить HANDL1 ввода PUSH STD_INPUT_HANDLE CALL GetStdHandle@4 MOV HANDL1,EAX ; преобразовать строки для вывода PUSH OFFSET TEXT PUSH OFFSET TEXT CALL CharToOemA@8 PUSH OFFSET FORM PUSH OFFSET FORM CALL CharToOemA@8 PUSH OFFSET FORM1 PUSH OFFSET FORM1 CALL CharToOemA@8 ; получить количество параметров CALL NUMPAR MOV PAR,EAX ; если параметр один, то искать в текущем каталоге CMP EAX, 1 JE NO_PAR ;---------------------------------- ; получить параметр номером EDI MOV EDI,2 LEA EBX,BUF CALL GETPAR CMP PAR,3 JB NO_PAR ; получить параметр - маску поиска MOV EDI,3 LEA EBX, MASKA CALL GETPAR NO_PAR: ;---------------------------------- PUSH OFFSET BUF CALL FIND ; вывести количество файлов PUSH NUMF PUSH OFFSET FORM PUSH OFFSET BUF CALL wsprintfA LEA EAX, BUF MOV EDX,1 CALL WRITE ;+++++++++++++++++ ; вывести количество каталогов PUSH NUMD PUSH OFFSET FORM1 PUSH OFFSET BUF CALL wsprintfA LEA EAX, BUF MOV EDX, 1 CALL WRITE _END: PUSH 0 CALL ExitProcess@4 ; область процедур ;************************************* ; вывести строку (в конце перевод строки) ; EAX - на начало строки ; EDX - с переводом строки или без WRITE PROC ; получить длину параметра PUSH EAX PUSH EAX CALL lstrlenA@4 MOV ESI,EAX POP EBX CMP EDX, 1 JNE NO_ENT ; в конце - перевод строки MOV BYTE PTR [EBX+ESI],13 MOV BYTE PTR [EBX+ESI+1],10 MOV BYTE PTR [EBX+ESI+2],0 ADD EAX,2 NO_ENT: ; вывод строки PUSH 0 PUSH OFFSET LENS PUSH EAX PUSH EBX PUSH HANDL CALL WriteConsoleA@20 RET WRITE ENDP

; процедура определения количества параметров в строке ; определить количество параметров (->EAX) NUMPAR PROC CALL GetCommandLineA@0 MOV ESI,EAX ; указатель на строку XOR ECX,ECX ; счетчик MOV EDX,1 ; признак L1: CMP BYTE PTR [ESI],0 JE L4 CMP BYTE PTR [ESI],32 JE L3 ADD ECX,EDX ; номер параметра MOV EDX,0 JMP L2 L3: OR EDX, 1 L2: INC ESI JMP L1 L4: MOV EAX,ECX RET NUMPAR ENDP

; получить параметр из командной строки ; EBX - указывает на буфер, куда будет помещен параметр ; в буфер помещается строка с нулем на конце ; EDI - номер параметра GETPAR PROC CALL GetCommandLineA@0 MOV ESI,EAX ; указатель на строку XOR ECX,ECX ; счетчик MOV EDX,1 ; признак L1: CMP BYTE PTR [ESI],0 JE L4 CMP BYTE PTR [ESI],32 JE L3 ADD ECX,EDX ; номер параметра MOV EDX,0 JMP L2 L3: OR EDX,1 L2: CMP ECX,EDI JNE L5 MOV AL, BYTE PTR [ESI] MOV BYTE PTR [EBX], AL INC EBX L5: INC ESI JMP L1 L4: MOV BYTE PTR [EBX], 0 RET GETPAR ENDP ;----------------------------------- ; поиск в каталоге файлов и их вывод ; локальные переменные FINDH EQU [EBP-4] ; дескриптор поиска DIRS EQU [EBP-304] ; полное имя файла DIRSS EQU [EBP-604] ; для хранения каталога DIRV EQU [EBP-904] ; для временного хранения DIR EQU [EBP+8] ; параметр - имя каталога FIND PROC PUSH EBP MOV EBP,ESP SUB ESP,904 ; инициализация локальных переменных MOV ECX,300 MOV AL,0 MOV EDI,0 CLR: MOV BYTE PTR DIRS+[EDI],AL MOV BYTE PTR DIRSS+[EDI],AL MOV BYTE PTR DIRV+[EDI],AL INC EDI LOOP CLR ; определить длину пути PUSH DIR CALL lstrlenA@4 MOV EBX,EAX MOV EDI, DIR CMP BYTE PTR [EDI],0 JE _OK ;если в конце нет "\" - добавим CMP BYTE PTR [EDI+EBX-1],"\" JE _OK PUSH OFFSET AP PUSH DWORD PTR DIR CALL lstrcatA@8 _OK: ; запомним каталог PUSH DWORD PTR DIR LEA EAX,DIRSS PUSH EAX CALL lstrcpyA@8 ; путь с маской PUSH OFFSET MASKA PUSH DWORD PTR DIR CALL lstrcatA@8 ; здесь начало поиска PUSH OFFSET FIN PUSH DWORD PTR DIR CALL FindFirstFileA@8 CMP EAX,-1 JE _ERR ; сохранить дескриптор поиска MOV FINDH,EAX LF: ; исключить "файлы" "." и ".." CMP BYTE PTR FIN.NAM,"." JE _FF ;--------------------- LEA EAX,DIRSS PUSH EAX LEA EAX,DIRS PUSH EAX CALL lstrcpyA@8 ;--------------------- PUSH OFFSET FIN.NAM LEA EAX, DIRS PUSH EAX CALL lstrcatA@8 ; не каталог ли? TEST BYTE PTR FIN.ATR, 10H JE NO_DIR ; добавить в строку <DIR> PUSH OFFSET DIRN LEA EAX, DIRS PUSH EAX CALL lstrcatA@8 ; увеличим счетчики INC NUMD DEC NUMF ; установим признак каталога MOV PRIZN,1 ; вывести имя каталога LEA EAX, DIRS PUSH EAX CALL OUTF JMP _NO NO_DIR: ; вывести имя файла LEA EAX, DIRS PUSH EAX CALL OUTF ; признак файла (не каталога) MOV PRIZN,0 _NO: CMP PRIZN,0 JZ _F ; каталог, готовимся в рекурсивному вызову LEA EAX,DIRSS PUSH EAX LEA EAX, DIRV PUSH EAX CALL lstrcpyA@8 PUSH OFFSET FIN.NAM LEA EAX,DIRV PUSH EAX CALL lstrcatA@8 ; осуществляем вызов LEA EAX, DIRV PUSH EAX CALL FIND ; продолжение поиска _F: INC NUMF _FF: PUSH OFFSET FIN PUSH DWORD PTR FINDH CALL FindNextFileA@8 CMP EAX,0 JNE LF ; закрыть дескриптор поиска PUSH DWORD PTR FINDH CALL FindClose@4 _ERR: MOV ESP, EBP POP EBP RET 4 FIND ENDP ;---------------------------------- ; страничный вывод имен найденных файлов STRN EQU [EBP+8] OUTF PROC PUSH EBP MOV EBP,ESP ; преобразовать строку PUSH DWORD PTR STRN PUSH DWORD PTR STRN CALL CharToOemA@8 ; здесь вывод результата MOV EAX, STRN MOV EDX, 1 CALL WRITE INC NUM ; конец страницы? CMP NUM, 22 JNE NO MOV NUM, 0 ; ждать ввод строки MOV EDX, 0 LEA EAX, TEXT CALL WRITE PUSH 0 PUSH OFFSET LENS PUSH 10 PUSH OFFSET BUFIN PUSH HANDL1 CALL ReadConsoleA@20 NO: POP EBP RET 4 OUTF ENDP _TEXT ENDS END START




Содержание  Назад  Вперед