Консультация № 136483
12.05.2008, 15:29
50.00 руб.
0 4 1
Уважаемые эксперты!
Необходимо разобраться с кодом на асме, желательно прокомментировав построчно. Как я понял, данная программа выводит информацию об всех дисках системы.

Буду очень благодарен если поможете разобраться<p><fieldset style=‘background-color:#EFEFEF; width:80%; border:1px solid; padding:10px;‘ class=fieldset><font color=#777777><i>Код перемещён в приложение.</i>
-----
</font><font size=1 color=#777777><b>• Отредактировал: <a href=http://rusfaq.ru/info/user/48029 target=_blank>skrech</a></b> (Профессионал)
<b>• Дата редактирования:</b> 13.05.2008, 16:07</font></fieldset>

Приложение:
.386 .MODEL FLAT,STDCALL locals jumps UNICODE = 0 include win32.inc includelib import32.lib IDC_STATIC equ -1 IDD_DIALOG1 equ 103 IDD_DIALOG2 equ 104 IDI_ICON equ 105 IDC_EDIT1 equ 1000 IDC_EDIT2 equ 1001 IDC_EDIT3 equ 1002 IDC_EDIT4 equ 1003 IDC_EDIT5 equ 1004 IDC_EDIT6 equ 1005 IDC_EDIT7 equ 1006 IDC_EDIT8 equ 1007 IDC_EDIT9 equ 1008 IDC_EDIT10 equ 1009 IDC_EDIT11 equ 1010 IDC_EDIT12 equ 1011 IDC_EDIT13 equ 1012 IDC_EDIT14 equ 1013 IDC_TEXT1 equ 3000 IDC_TEXT2 equ 3001 IDC_TEXT3 equ 3002 IDC_TEXT4 equ 3003 IDC_TEXT5 equ 3004 IDC_TEXT6 equ 3005 IDC_TEXT7 equ 3006 IDC_TEXT8 equ 3007 IDC_TEXT9 equ 3008 IDC_TEXT10 equ 3009 IDC_TEXT11 equ 3010 IDC_TEXT12 equ 3011 ICON_SMALL equ 0 IDDEC equ 2000 IDINC equ 2001 IDEXIT equ 2003 IDHLP equ 2002 IDM_ABO equ 4001 IDM_EXIT equ 4002 .DATA hInst dd ? hIcon dd ? fmat1 db "%lu", 0 fmat2 db "%lX", 0 msg MSGSTRUCT <?> pnt PAINTSTRUCT <?> rect RECT <> DlgWidth dd ? DlgHeight dd ? DesktopRect RECT <> cdrive db ‘a:‘, 0 ddrive db ‘a‘ DriveType dd 0 Tot_clust dd 0 Free_clust dd 0 BytesPSect dd 0 SectPClust dd 0 vol_filenames equ 16 vol_filename db vol_filenames dup(0) vol_filesys dd 0 vol_Maxfilelen dd 0 vol_serial dd 0 vol_Names equ 16 vol_Name db vol_Names dup(0) net_Names dd 32 net_Name db 32 dup(0) numbuff db 64 dup(0) TypeTab dd offset nullst dd offset nullst dd offset TypeID2 dd offset TypeID3 dd offset TypeID4 dd offset TypeID5 dd offset TypeID6 TypeID2 db ‘ (Removable)‘, 0,0,0,0 TypeID3 db ‘ (Fixed)‘, 0,0,0,0,0,0,0,0 TypeID4 db ‘ (Network)‘, 0,0,0,0,0,0 TypeID5 db ‘ (CD-ROM)‘, 0,0,0,0,0,0,0 TypeID6 db ‘ (RamDisk)‘, 0,0,0,0,0,0 nullst db 16 dup(0) .CODE main: mov eax, offset jjj call GetModuleHandle, NULL mov hInst, eax call DialogBoxParamA, hInst, IDD_DIALOG1, 0, offset DlgProc, 0 call ExitProcess DlgProc PROC hwnd:DWORD, wmsg:DWORD, wparam:DWORD, lparam:DWORD mov eax, wmsg cmp ax, WM_DESTROY je wmdestroy cmp ax, WM_CLOSE je wmdestroy cmp ax, WM_COMMAND je wmcommand cmp ax, WM_INITDIALOG je initdlg cmp ax, WM_PAINT je paint xor eax,eax ret wmdestroy: call EndDialog, hwnd, 0 call ExitProcess ret wmcommand: cmp wparam, IDEXIT je wmdestroy cmp wparam, IDINC jne noinc call GetDlgItem, hwnd, IDDEC call EnableWindow, eax, true ; Enable DEC Button mov al, byte ptr [offset cdrive] mov byte ptr [offset ddrive], al lb_1: inc byte ptr [offset cdrive] cmp byte ptr [offset cdrive], ‘z‘ jbe notou1 mov al, byte ptr [offset ddrive] mov byte ptr [offset cdrive], al call GetDlgItem, hwnd, IDINC call EnableWindow, eax, false ret notou1: call GetDriveTypeA, offset cdrive cmp eax, 1 jbe lb_1 call GetDriveI, hwnd ret noinc: cmp wparam, IDDEC jne nodec call GetDlgItem, hwnd, IDINC call EnableWindow, eax, true mov al, byte ptr [offset cdrive] mov byte ptr [offset ddrive], al lb_2: dec byte ptr [offset cdrive] cmp byte ptr [offset cdrive], ‘a‘ jae notou2 mov al, byte ptr [offset ddrive] mov byte ptr [offset cdrive], al call GetDlgItem, hwnd, IDDEC call EnableWindow, eax, false ret notou2: call GetDriveTypeA, offset cdrive cmp eax, 1 jbe lb_2 call GetDriveI, hwnd ret nodec: cmp wparam, IDM_ABO jne nohlp call GetModuleHandle, NULL call DialogBoxParamA, eax, IDD_DIALOG2, hwnd, offset DlgProc2, 0 nohlp: cmp wparam, IDM_EXIT jne noext jmp wmdestroy noext: xor eax, eax ret initdlg: call GetWindowRect, hwnd, offset rect call GetDesktopWindow call GetWindowRect, eax, offset DesktopRect mov eax, rect.rcBottom sub eax, rect.rcTop mov DlgHeight, eax mov eax, rect.rcRight sub eax, rect.rcLeft mov DlgWidth, eax mov ebx, DesktopRect.rcBottom sub ebx, DlgHeight shr ebx, 1 mov ecx, DesktopRect.rcRight sub ecx, DlgWidth shr ecx, 1 call MoveWindow, hwnd, ecx, ebx, DlgWidth, DlgHeight, 0 call GetDriveI, hwnd ret paint: call BeginPaint, hwnd, offset pnt call EndPaint, hwnd, offset pnt ret DlgProc endp DlgProc2 PROC hwnd:DWORD, wmsg:DWORD, wparam:DWORD, lparam:DWORD mov eax, wmsg cmp ax, WM_DESTROY je wmdestroy2 cmp ax, WM_CLOSE je wmdestroy2 cmp ax, WM_COMMAND je wmcommand2 cmp ax, WM_INITDIALOG je initdlg2 cmp ax, WM_PAINT je paint2 xor eax,eax ret wmdestroy2: call EndDialog, hwnd, 0 ret paint2: call BeginPaint, hwnd, offset pnt call EndPaint, hwnd, offset pnt ret initdlg2: call GetWindowRect, hwnd, offset rect call GetDesktopWindow call GetWindowRect, eax, offset DesktopRect mov eax, rect.rcBottom sub eax, rect.rcTop mov DlgHeight, eax mov eax, rect.rcRight sub eax, rect.rcLeft mov DlgWidth, eax mov ebx, DesktopRect.rcBottom sub ebx, DlgHeight shr ebx, 1 mov ecx, DesktopRect.rcRight sub ecx, DlgWidth shr ecx, 1 call MoveWindow, hwnd, ecx, ebx, DlgWidth, DlgHeight, 0 ret wmcommand2: cmp wparam, IDOK jne nook jmp wmdestroy2 nook: ret DlgProc2 endp GetDriveI proc hDlg:dword call SetDlgItemTextA, hDlg, IDC_EDIT1, offset cdrive call GetDriveTypeA, offset cdrive cmp eax, 1 jbe notva mov DriveType, eax call jprintf, offset numbuff, offset fmat1, DriveType mov esi, offset numbuff fend1: lodsb or al, al jnz fend1 dec esi ; Overwrite 0 mov edi, esi ; edi -> mov esi, DriveType cmp esi, 6 ja nocand mov esi, dword ptr [offset TypeTab + esi*4] mov ecx, 16 rep movsb mov eax, true cmp DriveType, 4 je isnetw mov eax, false isnetw: push eax call GetDlgItem, hwnd, IDC_TEXT12 push eax call EnableWindow nocand: call SetDlgItemTextA, hDlg, IDC_EDIT8, offset numbuff push offset Tot_clust push offset Free_clust push offset BytesPSect push offset SectPClust push offset cdrive call GetDiskFreeSpaceA call jprintf, offset numbuff, offset fmat1, SectPClust call SetDlgItemTextA, hDlg, IDC_EDIT2, offset numbuff call jprintf, offset numbuff, offset fmat1, BytesPSect call SetDlgItemTextA, hDlg, IDC_EDIT3, offset numbuff call jprintf, offset numbuff, offset fmat1, Free_clust call SetDlgItemTextA, hDlg, IDC_EDIT4, offset numbuff call jprintf, offset numbuff, offset fmat1, Tot_clust call SetDlgItemTextA, hDlg, IDC_EDIT5, offset numbuff jjj: mov eax, Tot_clust cdq imul SectPClust imul BytesPSect call PutBytes call SetDlgItemTextA, hDlg, IDC_EDIT13, offset numbuff mov eax, Free_clust cdq imul SectPClust imul BytesPSect call PutBytes call SetDlgItemTextA, hDlg, IDC_EDIT14, offset numbuff push vol_filenames push offset vol_filename push offset vol_filesys push offset vol_Maxfilelen push offset vol_serial push vol_Names push offset vol_Name push offset cdrive call GetVolumeInformationA call jprintf, offset numbuff, offset fmat1, vol_Maxfilelen call SetDlgItemTextA, hDlg, IDC_EDIT6, offset numbuff call jprintf, offset numbuff, offset fmat2, vol_filesys call SetDlgItemTextA, hDlg, IDC_EDIT7, offset numbuff call jprintf, offset numbuff, offset fmat2, vol_serial call SetDlgItemTextA, hDlg, IDC_EDIT10, offset numbuff call SetDlgItemTextA, hDlg, IDC_EDIT11, offset vol_filename call SetDlgItemTextA, hDlg, IDC_EDIT9, offset vol_Name push offset net_Names push offset net_Name push 1 push offset cdrive call WNetGetUniversalNameA mov esi, dword ptr [offset net_Name] or esi, esi jnz nonet1 mov esi, offset nullst nonet1: call SetDlgItemTextA, hDlg, IDC_EDIT12, esi notva: ret GetDriveI endp PutBytes proc or edx, edx jnz isbig3 ; If > 4Gig cmp eax, 1024 ; > 1k? jae isbig1 call jprintf, offset numbuff, offset fmat1, eax ret isbig1: cmp eax, 1024*1024 jae isbig2 mov si, ‘bK‘ dok: mov ecx, 1024 mov ebx, 1000 idiv ecx mov ecx, eax mov eax, edx cdq imul ebx mov ebx, 1024 idiv ebx push esi push eax call jprintf, offset numbuff, offset fmat1, ecx pop eax call fendnum mov byte ptr [edi], ‘.‘ inc edi cmp eax, 100 jae okl1 mov byte ptr [edi], ‘0‘ inc edi cmp eax, 10 jae okl1 mov byte ptr [edi], ‘0‘ inc edi okl1: call jprintf, edi, offset fmat1, eax call fendnum pop esi mov byte ptr [edi], ‘ ‘ mov word ptr [edi + 1], si mov byte ptr [edi + 3], 0 ret isbig2: cmp eax, 1024*1024*1024 jae isbig3 mov ecx, 1024 idiv ecx cdq mov si, ‘bM‘ jmp dok isbig3: mov ecx, 1024 * 1024 idiv ecx cdq mov si, ‘bG‘ jmp dok PutBytes endp fendnum proc mov edi, offset numbuff lopfs: cmp byte ptr [edi], 0 je fouio inc edi jmp lopfs fouio: ret fendnum endp jprintf proc p1:dword, p2:dword, p3:dword push p3 push p2 push p1 call _wsprintfA add esp, 12 ret jprintf endp ends end main За доп информацией пишите пожалуйста на mirimas@mail.ru

Обсуждение

давно
Посетитель
7438
7205
13.05.2008, 15:58
общий
это ответ
Здравствуйте, Mirimas!
Держите текст с комментариями в прикрепленном файле либо читайте в мини-форуме
Об авторе:
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен
Неизвестный
13.05.2008, 19:59
общий
.386 ;допустимы команды и регистры 386+ процессора, ; кроме того, необходимо для модели flat.MODEL FLAT,STDCALL ;плоская модель памяти flat (все адресуется только смещениями) ;необходима для программ под Windows ; кроме того, STDCALL задает способ передачи параметров через стек ; (первым передается последний) и способ извлечения параметров ; из стека (по RET <n>). Этот способ используется почти всеми WinAPIlocals ;Разрешение идентификаторов с локальной областью действияjumps ;Разрешение автоматического решения проблемы коротких адресов ; в командах условного переходаUNICODE = 0 ;Будем использовать ANSI строки ;Не сильно и нужна, нигде не используется... ;Везде явно упоминаются ANSI-версии.include win32.inc ;описание констант, структур, внешних именincludelib import32.lib ;библиотека импортаIDC_STATIC equ -1 ;ID неизменяемых статических строкIDD_DIALOG1 equ 103 ;ID основного диалогаIDD_DIALOG2 equ 104 ;ID диалога AboutIDI_ICON equ 105 ;ID иконки 32х32 (не используется)IDC_EDIT1 equ 1000 ;ID Edit-а "Drive Letter:"IDC_EDIT2 equ 1001 ;ID Edit-а "Секторов в кластере"IDC_EDIT3 equ 1002 ;ID Edit-а "Байт в секторе"IDC_EDIT4 equ 1003 ;ID Edit-а "Свободных кластеров"IDC_EDIT5 equ 1004 ;ID Edit-а "Всего кластеров"IDC_EDIT6 equ 1005 ;ID Edit-а "Max filename length:"IDC_EDIT7 equ 1006 ;ID Edit-а "File system flags: "IDC_EDIT8 equ 1007 ;ID Edit-а "Тип носителя"IDC_EDIT9 equ 1008 ;ID Edit-а "Метка тома"IDC_EDIT10 equ 1009 ;ID Edit-а "Серийный номер"IDC_EDIT11 equ 1010 ;ID Edit-а "Файловая система"IDC_EDIT12 equ 1011 ;ID Edit-а "Network Name:"IDC_EDIT13 equ 1012 ;ID Edit-а "Общая ёмкость"IDC_EDIT14 equ 1013 ;ID Edit-а "Свободно"IDC_TEXT1 equ 3000 ;ID STATIC Control-а "Drive Letter:" (можно было использовать IDC_STATIC)IDC_TEXT2 equ 3001 ;ID STATIC Control-а "Секторов в кластере" (можно было использовать IDC_STATIC)IDC_TEXT3 equ 3002 ;ID STATIC Control-а "Байт в секторе" (можно было использовать IDC_STATIC)IDC_TEXT4 equ 3003 ;ID STATIC Control-а "Свободных кластеров" (можно было использовать IDC_STATIC)IDC_TEXT5 equ 3004 ;ID STATIC Control-а "Всего кластеров" (можно было использовать IDC_STATIC)IDC_TEXT6 equ 3005 ;ID STATIC Control-а "Max filename length:" (можно было использовать IDC_STATIC)IDC_TEXT7 equ 3006 ;ID STATIC Control-а "File system flags: " (можно было использовать IDC_STATIC)IDC_TEXT8 equ 3007 ;ID STATIC Control-а "Тип носителя" (можно было использовать IDC_STATIC)IDC_TEXT9 equ 3008 ;ID STATIC Control-а "Метка тома" (можно было использовать IDC_STATIC)IDC_TEXT10 equ 3009 ;ID STATIC Control-а "Серийный номер" (можно было использовать IDC_STATIC)IDC_TEXT11 equ 3010 ;ID STATIC Control-а "Файловая система" (можно было использовать IDC_STATIC)IDC_TEXT12 equ 3011 ;ID STATIC Control-а "Network Name:". Этот ID нужен, мы с этим STATIC работаемICON_SMALL equ 0 ;ID иконки 16х16 (не используется)IDDEC equ 2000 ;ID кнопки "Back"IDINC equ 2001 ;ID кнопки "Next"IDEXIT equ 2003 ;ID кнопки "Exit"IDHLP equ 2002 ;ID не используемой кнопки "Help"IDM_ABO equ 4001 ;ID команды из меню "Help\About"IDM_EXIT equ 4002 ;ID команды из меню "File\Exit".DATA ;Сегмент данных ;Глобальные переменныеhInst dd ? ;handle экземпляра программыhIcon dd ? ;handle иконки (не используется)fmat1 db "%lu", 0 ;Формат "длинный целый" для преобразования числа в строкуfmat2 db "%lX", 0 ;Формат "длинный 16-ричный" для преобразования числа в строкуmsg MSGSTRUCT <?> ;Структура, необходимая для обработки сообщений системыpnt PAINTSTRUCT <?> ;Структура, необходимая для рисования по WM_PAINTrect RECT <> ;Структура для координат прямоугольной зоны чего-либоDlgWidth dd ? ;Переменная для сохранения ширины диалогаDlgHeight dd ? ;Переменная для сохранения высоты диалогаDesktopRect RECT <> ;Структура для координат прямоугольной зоны "рабочего стола"cdrive db ‘a:\‘, 0 ;Начальная строка, задающая корневой путь текущего устройстваddrive db ‘a‘ ;текущее устройствоDriveType dd 0 ;Тип устройстваTot_clust dd 0 ;Общее число кластеровFree_clust dd 0 ;Число свободных кластеровBytesPSect dd 0 ;Байтов на секторSectPClust dd 0 ;Секторов на кластерvol_filenames equ 16 ;Длина имени файловой системыvol_filename db vol_filenames dup(0) ;Имя файловой системы (FAT, NTFS...)vol_filesys dd 0 ;Файловая системаvol_Maxfilelen dd 0 ;Максимальная длина именvol_serial dd 0 ;Серийный номерvol_Names equ 16 ;Длина имени томаvol_Name db vol_Names dup(0) ;Имя томаnet_Names dd 32 ;Длина запрашиваемой информацииnet_Name db 32 dup(0) ;Сетевое имяnumbuff db 64 dup(0) ;Буфер для преобразования числа в строкуTypeTab dd offset nullst ;Таблица имен типов устройств dd offset nullst dd offset TypeID2 ;2 - дискета, флэш dd offset TypeID3 ;3 - жесткий диск dd offset TypeID4 ;4 - сетевой диск dd offset TypeID5 ;5 - CD, DVD dd offset TypeID6 ;6 - Memory diskTypeID2 db ‘ (Removable)‘, 0,0,0,0TypeID3 db ‘ (Fixed)‘, 0,0,0,0,0,0,0,0TypeID4 db ‘ (Network)‘, 0,0,0,0,0,0TypeID5 db ‘ (CD-ROM)‘, 0,0,0,0,0,0,0TypeID6 db ‘ (RamDisk)‘, 0,0,0,0,0,0nullst db 16 dup(0) ;Пустая строка.CODE ;Сегмент кода;----------------------------------------------------------------------main: ;Точка входа; mov eax, offset jjj ;Это лишнее, видать осталсь от каких-то экспериментов call GetModuleHandle, NULL ;Получим handle приложения mov hInst, eax ;Сохраним call DialogBoxParamA, hInst, IDD_DIALOG1, 0, offset DlgProc, 0 ;Создадим основной диалог IDD_DIALOG1 из ресурсов ;нашего приложения (hInst) с функцией окна DlgProc call ExitProcess ;Выход ;Из дальнейшей логики можно увидеть, что сюда мы никогда не попадем... ;Программа вызывает ExitProcess в отработке WM_DESTROY... ;----------------------------------------------------------------------DlgProc PROC hwnd:DWORD, wmsg:DWORD, wparam:DWORD, lparam:DWORD ;Функция окна диалога mov eax, wmsg ;Анализируем приходящие сообщения cmp ax, WM_DESTROY ;Сообщение приходит, когда завершаем диалог je wmdestroy cmp ax, WM_CLOSE ;Сообщение приходит, когда нажимаем на кнопку "х" на заголовке окна je wmdestroy cmp ax, WM_COMMAND ;Сообщение приходит, когда нажимаем на кнопки диалога je wmcommand cmp ax, WM_INITDIALOG ;Сообщение приходит в начале инициализации диалога je initdlg cmp ax, WM_PAINT ;Сообщение приходит при перерисовке окна je paint xor eax,eax ;Остальные сообщения не отрабатываем ret;----------------------------------------------------------------------wmdestroy: call EndDialog, hwnd, 0 ;Завершаем диалог call ExitProcess ;Выход из программы (смотри замечание выше) ;Где-то можно убрать, "правильнее" здесь ret;----------------------------------------------------------------------wmcommand: cmp wparam, IDEXIT ;Кнопка "Exit"? je wmdestroy ;Идем сразу на завершение диалога ;"Правильнее" послать себе сообщение SendMessage(hwnd,WM_CLOSE,0,0) cmp wparam, IDINC ;Кнопка "Next"? jne noinc ; Нет? идем на дальнейшую проверку call GetDlgItem, hwnd, IDDEC ;Handle кнопки "Back" call EnableWindow, eax, true ;Разрешаем кнопку mov al, byte ptr [offset cdrive] ; сохраним текущую букву устройства mov byte ptr [offset ddrive], al ; в ddrivelb_1: inc byte ptr [offset cdrive] ;Инкрементируем букву устройства cmp byte ptr [offset cdrive], ‘z‘ ;Дошли до последней возможной? jbe notou1 ;Если нет, то отрабатываем mov al, byte ptr [offset ddrive] ;Иначе, mov byte ptr [offset cdrive], al ; восстанавливаем последнее значение call GetDlgItem, hwnd, IDINC ;Handle кнопки "Next" call EnableWindow, eax, false ;Запрещаем кнопку retnotou1: ;Буква корректна call GetDriveTypeA, offset cdrive ;Получаем тип устройства cmp eax, 1 ;Если 0 или 1, то такого устройства нет jbe lb_1 ;Идем на поиск следующего устройства call GetDriveI, hwnd ;Получаем и показываем информацию об устройстве ret;----------------------------------------------------------------------noinc: cmp wparam, IDDEC ;Кнопка "Back"? jne nodec ; Нет? идем на дальнейшую проверку call GetDlgItem, hwnd, IDINC ;Handle кнопки "Next" call EnableWindow, eax, true ;Разрешаем кнопку mov al, byte ptr [offset cdrive] ; сохраним текущую букву устройства mov byte ptr [offset ddrive], al ; в ddrivelb_2: dec byte ptr [offset cdrive] ;Декркментируем букву устройства cmp byte ptr [offset cdrive], ‘a‘ ;Дошли до первой? jae notou2 ;Если нет, то отрабатываем mov al, byte ptr [offset ddrive] ;Иначе, mov byte ptr [offset cdrive], al ; восстанавливаем последнее значение call GetDlgItem, hwnd, IDDEC ;Handle кнопки "Back" call EnableWindow, eax, false ;Запрещаем кнопку retnotou2: ;Буква корректна call GetDriveTypeA, offset cdrive ;Получаем тип устройства cmp eax, 1 ;Если 0 или 1, то такого устройства нет jbe lb_2 ;Идем на поиск следующего устройства call GetDriveI, hwnd ;Получаем и показываем информацию об устройстве retnodec: cmp wparam, IDM_ABO ;Кнопка "Exit"? jne nohlp ; Нет? идем на дальнейшую проверку call GetModuleHandle, NULL ;Получим handle приложения ;Хотя мы его уже храним в hInst... call DialogBoxParamA, eax, IDD_DIALOG2, hwnd, offset DlgProc2, 0 ;Создадим диалог "About" IDD_DIALOG2 из ресурсов ;нашего приложения с функцией окна DlgProc2 ret ;Пропущена команда... ; Хотя работает и без нее, просто отработает по следующей ret...nohlp: cmp wparam, IDM_EXIT ;Кнопка "Exit"? jne noext ; Нет? Заканчиваем анализ jmp wmdestroy ;Завершаем диалог ;"Правильнее" послать себе сообщение SendMessage(hwnd,WM_CLOSE,0,0)noext: xor eax, eax ;Остальное не наше ret;---------------------------------------initdlg: ;Начальная инициализация диалога; call LoadIcon, hInst, IDI_ICON; mov hIcon, eax call GetWindowRect, hwnd, offset rect ;Получим координаты окна диалога call GetDesktopWindow ;Получим handle "рабочего стола" call GetWindowRect, eax, offset DesktopRect ;Получим координаты окна "рабочего стола" ;Отцентрируем наше окно mov eax, rect.rcBottom sub eax, rect.rcTop ;В EAX высота нашего диалога mov DlgHeight, eax ;Сохраним mov eax, rect.rcRight sub eax, rect.rcLeft ;В EAX ширина нашего диалога mov DlgWidth, eax ;Сохраним mov ebx, DesktopRect.rcBottom ;В EBX высота "рабочего стола" sub ebx, DlgHeight ;Минус высота диалога shr ebx, 1 ;Пополам, получим в EBX стартовый Y диалога mov ecx, DesktopRect.rcRight ;В ECX ширина "рабочего стола" sub ecx, DlgWidth ;Минус ширина диалога shr ecx, 1 ;Пополам, получим в ECX стартовый X диалога call MoveWindow, hwnd, ecx, ebx, DlgWidth, DlgHeight, 0 ;Перемещаем диалог call GetDriveI, hwnd ;И показываем информацию об первом устройстве (А:) ;Кстати, если устройства A нет в системе, то будут пустые поля ... ;"Правильнее", наверное, сделать как по кнопке "Next": ; с проверкой и автоинкрементом... Впрочем, допустимо и так... ret;----------------------------------------------------------------------paint: ;Отрисовка окна ;Вообще говоря, она лишняя (когда было рисование иконки,то было нужно...) ;Система все равно сама отрисовывает call BeginPaint, hwnd, offset pnt ;Начало; push hIcon ; Icon Handle; push 204 ; Start Y; push 10 ; Start X; push eax ; The hDc (returned by BeginPaint); call DrawIcon ; Draw it call EndPaint, hwnd, offset pnt ;Конец retDlgProc endp ;Конец функции окна основного диалога;----------------------------------------------------------------------DlgProc2 PROC hwnd:DWORD, wmsg:DWORD, wparam:DWORD, lparam:DWORD ;Функция окна диалога "About" mov eax, wmsg ;Все аналогично cmp ax, WM_DESTROY je wmdestroy2 cmp ax, WM_CLOSE je wmdestroy2 cmp ax, WM_COMMAND je wmcommand2 cmp ax, WM_INITDIALOG je initdlg2 cmp ax, WM_PAINT je paint2 xor eax,eax ret;----------------------------------------------------------------------wmdestroy2: call EndDialog, hwnd, 0 retpaint2: call BeginPaint, hwnd, offset pnt call EndPaint, hwnd, offset pnt retinitdlg2: ;Аналогично, центрируем окно call GetWindowRect, hwnd, offset rect call GetDesktopWindow call GetWindowRect, eax, offset DesktopRect mov eax, rect.rcBottom sub eax, rect.rcTop mov DlgHeight, eax ;Высота окна mov eax, rect.rcRight sub eax, rect.rcLeft mov DlgWidth, eax ;Ширина окна mov ebx, DesktopRect.rcBottom sub ebx, DlgHeight shr ebx, 1 ;ebx = Start y mov ecx, DesktopRect.rcRight sub ecx, DlgWidth shr ecx, 1 ;ecx = Start x call MoveWindow, hwnd, ecx, ebx, DlgWidth, DlgHeight, 0 ; Центрируем retwmcommand2: cmp wparam, IDOK ;Выходим по кнопке "Ok" jne nook jmp wmdestroy2nook: retDlgProc2 endp;----------------------------------------------------------------------GetDriveI proc hDlg:dword ;Получение и отображение информации об устройстве ;Параметр - handle диалога call SetDlgItemTextA, hDlg, IDC_EDIT1, offset cdrive ;Задаем путь корня диска call GetDriveTypeA, offset cdrive ;Проверим тип диска cmp eax, 1 ;Если 0 или 1, то выходим, поля останутся незаполненными jbe notva ; (см замечание для initdlg основного окна) mov DriveType, eax ;Сохраним call jprintf, offset numbuff, offset fmat1, DriveType;Преобразуем число типа в символьную строку в буфере numbuff mov esi, offset numbuff ;адрес буфераfend1: ;Цикл поиска позиции завершающего нуля lodsb ;Читаем очередной байт, esi автоматом инкрементируется or al, al ;проверим на 0 jnz fend1 ;повторим dec esi ;esi - адрес нуля mov edi, esi ;сохраним в edi адрес, куда писать mov esi, DriveType ;Номер типа cmp esi, 6 ;Проверим на максимальный ja nocand ;Для неизвестного типа пропустим добавление текста mov esi, dword ptr [offset TypeTab + esi*4] ;В esi адрес строки из таблицы mov ecx, 16 ;длина строки rep movsb ;копируя [esi]->[edi], добавим название типа носителя mov eax, true cmp DriveType, 4 ;Для сетевого диска разрешим "Network Name" je isnetw mov eax, false ;Для всех остальных запрещаемisnetw: push eax ;true/false для EnableWindow call GetDlgItem, hwnd, IDC_TEXT12 ;Получим handle STATIC-а "Network Name" push eax call EnableWindow ;Enable/Disable STATIC-аnocand: call SetDlgItemTextA, hDlg, IDC_EDIT8, offset numbuff;Передадим сформированную строку в Edit "Тип носителя" push offset Tot_clust ;Общее число кластеров push offset Free_clust ;Число свободных кластеров push offset BytesPSect ;Байтов на сектор push offset SectPClust ;Секторов на кластер push offset cdrive ;устройство call GetDiskFreeSpaceA ;Получим информацию об устройстве, параметрами адреса соотв.перем. ;Сформируем соответствующие числовые строки ; и передадим в соответствующий Edit для отображения call jprintf, offset numbuff, offset fmat1, SectPClust call SetDlgItemTextA, hDlg, IDC_EDIT2, offset numbuff ;Секторов на кластер call jprintf, offset numbuff, offset fmat1, BytesPSect call SetDlgItemTextA, hDlg, IDC_EDIT3, offset numbuff ;Байтов на сектор call jprintf, offset numbuff, offset fmat1, Free_clust call SetDlgItemTextA, hDlg, IDC_EDIT4, offset numbuff ;Число свободных кластеров call jprintf, offset numbuff, offset fmat1, Tot_clust call SetDlgItemTextA, hDlg, IDC_EDIT5, offset numbuff ;Общее число кластеров;jjj: ;Непонятно зачем... mov eax, Tot_clust ;Посчитаем общую ёмкость; cdq ;Лишнее imul SectPClust imul BytesPSect ;edx:eax = Tot_clust * SectPClust * BytesPSect байт call PutBytes ;Преобразуем в строку, с учетом Гбайт, Мбайт... call SetDlgItemTextA, hDlg, IDC_EDIT13, offset numbuff ;передадим в Edit для отображения mov eax, Free_clust ;Посчитаем общий свободный объём; cdq ;Лишнее imul SectPClust imul BytesPSect ;edx:eax = Free_clust * SectPClust * BytesPSect байт call PutBytes ;Преобразуем в строку, с учетом Гбайт, Мбайт... call SetDlgItemTextA, hDlg, IDC_EDIT14, offset numbuff ;передадим в Edit для отображения;---------------------------------------------------------------------- push vol_filenames ;Длина имени файловой системы push offset vol_filename ;Имя файловой системы (FAT, NTFS...) push offset vol_filesys ;Флаги Файловой системы push offset vol_Maxfilelen ;Максимальная длина имен push offset vol_serial ;Серийный номер push vol_Names ;Длина имени тома push offset vol_Name ;Имя тома push offset cdrive ;устройство call GetVolumeInformationA ;Запросим информацию о томе ;Если надо, сформируем соответствующие числовые строки ; и передадим в соответствующий Edit для отображения call jprintf, offset numbuff, offset fmat1, vol_Maxfilelen call SetDlgItemTextA, hDlg, IDC_EDIT6, offset numbuff ;Максимальная длина имен call jprintf, offset numbuff, offset fmat2, vol_filesys call SetDlgItemTextA, hDlg, IDC_EDIT7, offset numbuff ;Флаги Файловой системы в HEX call jprintf, offset numbuff, offset fmat2, vol_serial call SetDlgItemTextA, hDlg, IDC_EDIT10, offset numbuff ;Серийный номер в HEX call SetDlgItemTextA, hDlg, IDC_EDIT11, offset vol_filename ;Имя файловой системы (FAT, NTFS...) call SetDlgItemTextA, hDlg, IDC_EDIT9, offset vol_Name ;Имя тома;---------------------------------------------------------------------- ;И, наконец, запросим сетевое имя ;Опять же, "правильнее" было бы запрашивать только для типа 4 ;Для всех остальнее очищать... push offset net_Names ;Длина поля сетевого имени push offset net_Name ;Адрес сетевого имени push 1 ;Тип запрашиваемой информации push offset cdrive ;Устройство call WNetGetUniversalNameA ;Запросим сетевое имя mov esi, dword ptr [offset net_Name] ;получим адрес строки or esi, esi ;Проверим ответ jnz nonet1 ;Что-то есть mov esi, offset nullst ;Иначе пустая строкаnonet1: call SetDlgItemTextA, hDlg, IDC_EDIT12, esi ;Отобразим в Edit-еnotva: retGetDriveI endp;----------------------------------------------------------------------------;PutBytes proc ;Преобразуем число EDX:EAX в строку, с учетом Гбайт, Мбайт... or edx, edx ;Если edx != 0, то > 4Гб jnz isbig3 ;И тогда считаем в Гб cmp eax, 1024 ;Если > 1024, jae isbig1 ; то считаем в Кб или Мб или Гб call jprintf, offset numbuff, offset fmat1, eax ;Байты ret ;И выходимisbig1: ;Число > 1024 cmp eax, 1024*1024 ;Если число > 1024*1024 jae isbig2 ; то считаем в Мб или Гб mov si, ‘bK‘ ;Иначе, в Кбdok: ;Формирование числа mov ecx, 1024 mov ebx, 1000 idiv ecx ;Разделим на 1024 mov ecx, eax ;ecx = частное, edx = остаток mov eax, edx ;Остаток - число 0-1023; cdq ;лишнее ;Чтобы отобразить остаток как тысячные, ; промасштабируем: умножим на 1000 и разделим на 1024 ; в результате получим число 0-999 imul ebx ;Умножим на 1000 mov ebx, 1024 idiv ebx ;Разделим на 1024 push esi ;Сохраним единицы измерения push eax ;Сохраним остаток call jprintf, offset numbuff, offset fmat1, ecx ;Сформируем строку из целого числа Гб, Мб, Кб pop eax ;Восстановим остаток call fendnum ;Ищем в numbuff позицию нуля, результат в edi mov byte ptr [edi], ‘.‘ ;разделяем целую часть числа от дробной точкой inc edi ; cmp eax, 100 ;Число из трех знаков, jae okl1 ;Если да, то преобразовываем mov byte ptr [edi], ‘0‘ ;Иначе, десятые - 0 inc edi ; cmp eax, 10 ;Число из двух знаков, jae okl1 ;Если да, то преобразовываем mov byte ptr [edi], ‘0‘ ;Иначе, сотые - 0 inc ediokl1: call jprintf, edi, offset fmat1, eax ;Формируем числовую строку ;(Можно было задать формат "%3.3u", и весь анализ не нужен...) call fendnum ;Ищем в numbuff позицию нуля, результат в edi pop esi ;Восстановим в si единицы измерения mov byte ptr [edi], ‘ ‘ ;Разделительный пробел mov word ptr [edi + 1], si ;Пишем mov byte ptr [edi + 3], 0 ;Конец строки ret ;Строка готова - выходимisbig2: ;Число > 1024*1024 cmp eax, 1024*1024*1024 ;Если > 1024*1024*1024, jae isbig3 ; то считаем в Гб ; иначе в Мб mov ecx, 1024 ;Считаем сколько Мб, idiv ecx ; для этого делим на 1024 cdq ;Подготовим edx для последующего деления mov si, ‘bM‘ ;Единица измерения jmp dok ;На формирование строки isbig3: ;Число > 1024*1024*1024 mov ecx, 1024 * 1024 ;Считаем в Гб idiv ecx ; для этого делим на 1024*1024 cdq ;Подготовим edx для последующего деления mov si, ‘bG‘ ;Единица измерения jmp dok ;На формирование строкиPutBytes endp;----------------------------------------------------------------------------;fendnum proc ;Ищем в numbuff позицию нуля, результат в edi mov edi, offset numbuff ; Тут понятно и без комментариев...lopfs: cmp byte ptr [edi], 0 je fouio inc edi jmp lopfsfouio: retfendnum endpjprintf proc p1:dword, p2:dword, p3:dword ;Обертка для вызова wsprintf для преобразования числа в строку push p3 ;У этой ф-ии способ передачи параметров - С push p2 ;Параметры передаются, начиная с последнего push p1 call _wsprintfA add esp, 12 ;Выкидывает вызывающая программа с помощью add esp,<n> retjprintf endp;----------------------------------------------------------------------ends end main ;Конец текста, точка входа - main
Неизвестный
14.05.2008, 13:03
общий
Каким образом эту программу можно запустить на срр (или делфи)? Написал: #include <conio.h>void main(){ asm{ ... }}но он выдаёт ошибки. Или где можно взять норм компилятор для асмы подскажите пожалуйста.
давно
Старший Модератор
31795
6196
14.05.2008, 17:53
общий
Компиляторы смотрите <a href=http://www.wasm.ru/toollist.php><b>тут</b></a>.Компилятор С вставляет свой код пролога и эпилога (перед и после кода самой программы), а программа на ассемблере всё это должна делать сама.
Об авторе:
Мне безразлично, что Вы думаете о обо мне, но я рад за Вас - Вы начали думать.

Форма ответа