Среда, 16.07.2025, 01:20
Приветствую Вас Гость | RSS
Главная | Каталог статей | Регистрация | Вход
.:: Меню ::.
.:: Категории каталога ::.
Разное [5]
Различные темы по программированию
Пакет SWT [4]
Практикуемся в написании оконных приложений на Java
Среды разработки, компиляторы и т.п [3]
Сравнения, описания, плюсы и минусы сред разработки. Сравнение компиляторов.
Java [8]
Объектно-ориентированные соображения.
Си++ [19]
Коротко и ясно
Ассемблер [6]
Машинные коды, побитно :)
Форма входа
.:: Поиск ::.
.:: Дополнительно ::.
    Хостинг от Loqo.ru
             .:: Коментируем ::.
Главная » Статьи » Текстовый материал » Ассемблер

Консольный и GUI вариант вывода дериктории на ассемблере.
Code
.386
.model flat, STDCALL
   
include windows.inc  
include kernel32.inc
includelib kernel32.lib

.data
num1 dd 0
mess dd 80
buf_v db 80 dup (0)
fn db "*.*",0
ps db 10

.data?
ffd WIN32_FIND_DATA <?>
fh dd ?
sh dd ?

.code
start: call FreeConsole
  call AllocConsole
   
  invoke GetStdHandle, STD_OUTPUT_HANDLE  
  mov sh, eax
   
  invoke FindFirstFile, ADDR fn, ADDR ffd
  mov fh, eax
  invoke FindNextFile, fh, ADDR ffd
  .WHILE eax != 0
  invoke FindNextFile, fh, ADDR ffd
  cmp eax,0
  jz exit
   
  mov esi,0
  mov edi, offset ffd.cFileName
  mov dl, [edi]
  .WHILE dl != 0
  mov dl, [edi]
  cmp dl,0
  inc edi
  inc esi
  .ENDW
  dec esi
  invoke WriteConsole, sh,ADDR ffd.cFileName, esi, ADDR num1, 0
  invoke WriteConsole, sh,ADDR ps,1, ADDR num1, 0
  .ENDW
exit:  
invoke FindClose, fh
  invoke GetStdHandle, STD_INPUT_HANDLE
  invoke ReadConsole, eax, ADDR buf_v, mess, ADDR num1, 0
  invoke ExitProcess, 0
end start

Консольный вариант.
FreeConsole и AllocConsole используются для создания отдельной консоли, т.е. если запускать программу в консоли, результат будет выдан не в это же окно, а будет открыта новая консоль.
Получаем хэндл вывода, сохраняем его в глобальную переменную sh, т.к. он понадобится немного позже.
Вызываем функцию поиска первого файла FindFirstFile, имя файла "*.*" (все файлы), от этой функции получаем хэндл поиска, который будем использовать для последующего поиска.
Результат поиска сохраняется в структуру WIN32_FIND_DATA, переменная ffd.
Первым найденым файлом является корневой каталог, отображаемый точкой, следующая функция FindNextFile вернёт следующий файл, а это будет текущий каталог, который отображается двумя точками.
Эти два каталога в этой программе не отображаются (так захотел),
программа будет не корректно работать в корневом каталоге из-за этого, одно имя файла исчезнет, главное об этом знать. (программа не совсем идеальна)
Дальше идёт цикл поиска следующего файла и вывод его имени на консоль.
В цикле имеется ещё один цикл для определения длины названия файла.
В конце вызываем функцию чтения с консоли для созерцания выведенного, и ExitProcess конечно-же. (куда без него)
Следующая прога, посерьёзнее.
Code
.386
.model flat, stdcall
option casemap:none

WinMain proto :DWORD,:DWORD,:DWORD,:DWORD

include windows.inc
include user32.inc
include kernel32.inc
include gdi32.inc
includelib user32.lib
includelib kernel32.lib
includelib gdi32.lib

.data
szClassName db "DlgClass",0
DlgName db "MyDialog",0
szAppName db "DirView",0
fn db "*.*",0

.data?
lpMetr TEXTMETRIC <?>
hInstance HINSTANCE ?
lppaint PAINTSTRUCT <?>
sF WIN32_FIND_DATA <?>
buffer db 512 dup(?)
buffer2 db 512 dup(?)
GloDlg db ?
LenName db ?
charHt dd ?

.const
IDC_NAME equ 1
IDC_PASS equ 2
IDC_GEN equ 3
IDC_EXIT equ 4

.code
start:
  invoke GetModuleHandle, NULL
  mov hInstance, eax
   
  invoke WinMain, hInstance, NULL, NULL, SW_SHOWDEFAULT
  invoke ExitProcess, eax
   
WinMain proc hInst:HINSTANCE, hPrevInst:HINSTANCE, CmdLine:LPSTR, CmdShow:DWORD
  LOCAL wc:WNDCLASSEX
  LOCAL msg:MSG
  LOCAL hDlg:HWND
  mov wc.cbSize, SIZEOF WNDCLASSEX
  mov wc.style, CS_HREDRAW or CS_VREDRAW
  mov wc.lpfnWndProc, OFFSET WndProc
  mov wc.cbClsExtra, NULL
  mov wc.cbWndExtra, DLGWINDOWEXTRA
  push hInst
  pop wc.hInstance
  mov wc.hbrBackground, COLOR_BTNFACE+1
  mov wc.lpszMenuName, NULL
  mov wc.lpszClassName, OFFSET szClassName
  ;invoke LoadIcon, NULL, IDI_APPLICATION
  invoke LoadIcon, hInst, 500 ; icon ID
  mov wc.hIcon, eax
  mov wc.hIconSm, eax
  invoke LoadCursor, NULL, IDC_ARROW
  mov wc.hCursor, eax
  invoke RegisterClassEx, addr wc
   
   
  ;------------------------------------------------
  invoke CreateWindowEx, 0, ADDR szClassName, ADDR szAppName, WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,0,0,hInstance,0
  mov hDlg, eax
  ;------------------------------------------------
  INVOKE ShowWindow, hDlg, SW_SHOWNORMAL
  INVOKE UpdateWindow, hDlg
;++++++++++++++++++++++++++++++++++++++++++++  
  .WHILE TRUE
  INVOKE GetMessage, ADDR msg, NULL, 0, 0
  .BREAK .IF (!eax)
  invoke IsDialogMessage, hDlg, ADDR msg
  .if eax==FALSE
  INVOKE TranslateMessage, ADDR msg
  INVOKE DispatchMessage, ADDR msg
  .endif
  .ENDW
;++++++++++++++++++++++++++++++++++++++++++++
  mov eax, msg.wParam
  ret
WinMain endp

WndProc proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM
  LOCAL hDlg:HWND
  LOCAL hFind:HWND
  LOCAL hDC : DWORD
  .IF uMsg == WM_CREATE
  invoke GetDC, hWnd
  mov hDC, eax
  invoke GetTextMetrics,hDC,ADDR lpMetr
  mov ebx, 0
  mov ebx,lpMetr.tmExternalLeading
  add ebx, lpMetr.tmHeight
  mov charHt, ebx
  invoke ReleaseDC,hWnd,hDC
  .ELSEIF uMsg == WM_DESTROY
  invoke PostQuitMessage, 0

  .ELSEIF uMsg == WM_PAINT

  invoke FindFirstFile, ADDR fn, ADDR sF
  mov hFind, eax
  invoke FindNextFile, hFind, ADDR sF
   
  invoke BeginPaint, hWnd, ADDR lppaint
  mov hDC, eax

  mov ebx,0
  .WHILE eax != 0
  invoke FindNextFile, hFind, ADDR sF
  cmp eax,0  
  jz exit
  mov esi,0
  mov edi, offset sF.cFileName
  mov dl, [edi]
  .WHILE dl !=0
  mov dl, [edi]
  cmp dl, 0
  inc edi
  inc esi
  .ENDW
  dec esi
  add ebx, charHt
  invoke TextOut,hDC, 5,ebx, ADDR sF.cFileName, esi

  .ENDW
  exit:
   
  invoke FindClose, hFind
  invoke EndPaint, hWnd, ADDR lppaint
   
  .ELSE
  invoke DefWindowProc, hWnd, uMsg, wParam, lParam
  ret
  .ENDIF
  xor eax,eax
  ret
WndProc endp

end start

Рассказывать всю структуру GUI приложения думаю не стоит, это можно найти в любом учебнике.
Принцип поиска здесь такой-же, что и в предыдущей программе.
Так как вывод осуществляется на голую форму по координатам, для вывода последующей строки нам понадобится увеличивать координату y.
Для того, чтобы грамотно её вычислить мы определяем функцией GetTextMetrics различные параметры строки в системе.
Например: высота символов, размер места между строками.
Данные возвращаемые функцией сохраняются в структуре TEXTMETRIC а имя ей в этой программе lpMetric.
Отмечу что первоначальное определение параметров строки происходит при создании окна при событии WM_CREATE, а вывод и поиск файлов при прорисовке экрана WM_PAINT, т.е. если вы захотите расширить экран, то поиск и вывод будет произведён снова. (в принципе так и должно быть)
Не забываем закрывать то, что открыли, а именно FindClose и EndPaint.
Немного о цикле определения длины имени файла.
Мною была допущена небольшая ошибка при использовании регистра EDX.
Принцип такой, помещаю в регистр символ по адресу EDI и сравниваю с нулём (признак конца строки).
Изначально я помещал значение в EDX, но так как регистр 32-х битный я получал туда сразу 4-е символа !!! Для получения одного символа нужно использовать 8-и битную младшую часть DX, те Dl.
Ну пока всё, размышляйте, пишите.
Категория: Ассемблер | Добавил: C0demaker (09.04.2009)
Просмотров: 2075 | Рейтинг: 0.0/0
Всего комментариев: 0

Добавлять комментарии могут только зарегистрированные пользователи.
[ Регистрация | Вход ]
Ant1 © 2025