14.12.2017, 11:12 [+3 UTC]
в нашей команде: 2 376 чел. | участники онлайн: 12 (рекорд: 21)

:: РЕГИСТРАЦИЯ

:: консультации

:: задать вопрос

:: все разделы

:: правила

:: новости

:: участники

:: доска почёта

:: форум

:: блоги

:: поиск

:: статистика

:: наш журнал

:: наши встречи

:: наша галерея

:: отзывы о нас

:: поддержка

:: руководство

Версия системы:
7.41 (25.02.2017)

Общие новости:
23.02.2017, 09:51

Форум:
14.12.2017, 11:04

Последний вопрос:
14.12.2017, 10:34

Последний ответ:
14.12.2017, 11:10

Последняя рассылка:
14.12.2017, 08:15

Писем в очереди:
0

Мы в соцсетях:

Наша кнопка:

RFpro.ru - здесь вам помогут!

Отзывы о нас:
11.06.2017, 17:53 »
Tati77
Огромное спасибо Андрею Владимировичу за консультацию и потраченное на меня время, добрейший души человек,умница! [вопрос № 191121, ответ № 275080]
18.09.2010, 12:03 »
Andrey Rew1791
Ответ звучит вполне логично. Большое спасибо. [вопрос № 179931, ответ № 263083]
20.06.2011, 15:58 »
Julia Mechenaya
Большое спасибо экспертам портала за неоценимую помощь.

РАЗДЕЛ • Assembler

Создание программ на языке Assembler.

[администратор рассылки: Лысков Игорь Витальевич (Старший модератор)]

Лучшие эксперты в этом разделе

Коцюрбенко Алексей aka Жерар
Статус: Мастер-Эксперт
Рейтинг: 543
Зенченко Константин Николаевич
Статус: Модератор
Рейтинг: 435
Лысков Игорь Витальевич
Статус: Старший модератор
Рейтинг: 299

Перейти к консультации №:
 

Консультация онлайн # 136483
Раздел: • Assembler
Автор вопроса: Mirimas
Отправлена: 12.05.2008, 15:29
Поступило ответов: 1

Уважаемые эксперты!
Необходимо разобраться с кодом на асме, желательно прокомментировав построчно. Как я понял, данная программа выводит информацию об всех дисках системы.

Буду очень благодарен если поможете разобраться

Код перемещён в приложение.
-----
• Отредактировал: skrech (Профессионал)
• Дата редактирования: 13.05.2008, 16:07

Приложение:

Состояние: Консультация закрыта

Ответ # 223323 от Лысков Игорь Витальевич (Старший модератор)

Здравствуйте, Mirimas!
Держите текст с комментариями в прикрепленном файле либо читайте в мини-форуме


Консультировал: Лысков Игорь Витальевич (Старший модератор)
Дата отправки: 13.05.2008, 15:58

Рейтинг ответа:

0

[подробно]

Сообщение
модераторам

Отправлять сообщения
модераторам могут
только участники портала.
ВОЙТИ НА ПОРТАЛ »
регистрация »

Мини-форум консультации № 136483

Посетитель

ID: 14422

# 1

= общий = | 13.05.2008, 19:59 | цитировать цитировать  | профиль профиль  |  отправить письмо в личную почту пейджер

.386 ;допустимы команды и регистры 386+ процессора, ; кроме того, необходимо для модели flat .MODEL FLAT,STDCALL ;плоская модель памяти flat (все адресуется только смещениями) ;необходима для программ под Windows ; кроме того, STDCALL задает способ передачи параметров через стек ; (первым передается последний) и способ извлечения параметров ; из стека (по RET ). Этот способ используется почти всеми WinAPI locals ;Разрешение идентификаторов с локальной областью действия 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 диалога About IDI_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_PAINT 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) ;Имя файловой системы (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 disk 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 ;Получим 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 ; в ddrive 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 ;Handle кнопки "Next" call EnableWindow, eax, false ;Запрещаем кнопку ret notou1: ;Буква корректна 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 ; в ddrive 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 ;Handle кнопки "Back" call EnableWindow, eax, false ;Запрещаем кнопку ret notou2: ;Буква корректна call GetDriveTypeA, offset cdrive ;Получаем тип устройства cmp eax, 1 ;Если 0 или 1, то такого устройства нет jbe lb_2 ;Идем на поиск следующего устройства call GetDriveI, hwnd ;Получаем и показываем информацию об устройстве ret nodec: 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 ;Конец ret DlgProc 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 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 ;ebx = Start y mov ecx, DesktopRect.rcRight sub ecx, DlgWidth shr ecx, 1 ;ecx = Start x call MoveWindow, hwnd, ecx, ebx, DlgWidth, DlgHeight, 0 ; Центрируем ret wmcommand2: cmp wparam, IDOK ;Выходим по кнопке "Ok" jne nook jmp wmdestroy2 nook: ret DlgProc2 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: ret GetDriveI 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 edi okl1: 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 lopfs fouio: ret fendnum endp jprintf proc p1:dword, p2:dword, p3:dword ;Обертка для вызова wsprintf для преобразования числа в строку push p3 ;У этой ф-ии способ передачи параметров - С push p2 ;Параметры передаются, начиная с последнего push p1 call _wsprintfA add esp, 12 ;Выкидывает вызывающая программа с помощью add esp, ret jprintf endp ;---------------------------------------------------------------------- ends end main ;Конец текста, точка входа - main


Посетитель

ID: 211457

# 2

= общий = | 14.05.2008, 13:03 | цитировать цитировать  | профиль профиль  |  отправить письмо в личную почту пейджер

Каким образом эту программу можно запустить на срр (или делфи)? Написал: #include <conio.h> void main() { asm{ ... } } но он выдаёт ошибки. Или где можно взять норм компилятор для асмы подскажите пожалуйста.

Зенченко Константин Николаевич
Модератор

ID: 31795

# 3

= общий = | 14.05.2008, 17:53 | цитировать цитировать  | профиль профиль  |  отправить письмо в личную почту пейджер

Компиляторы смотрите тут. Компилятор С вставляет свой код пролога и эпилога (перед и после кода самой программы), а программа на ассемблере всё это должна делать сама.

 

Возможность оставлять сообщения в мини-форумах консультаций доступна только после входа в систему.
Воспользуйтесь кнопкой входа вверху страницы, если Вы зарегистрированы или пройдите простую процедуру регистрации на Портале.

Яндекс Rambler's Top100

главная страница | поддержка | задать вопрос

Время генерирования страницы: 0.15551 сек.

© 2001-2017, Портал RFPRO.RU, Россия
Авторское право: ООО "Мастер-Эксперт Про"
Калашников О.А.  |  Гладенюк А.Г.
Версия системы: 7.41 от 25.02.2017
Бесплатные консультации онлайн