Привет - Моя первая программа

Всё, что касается программирования на старых языках или для старых систем

Привет - Моя первая программа

Сообщение luzga » 06 май 2026, 13:47

Руководство для начинающего программиста или интересующегося.
Загрузив прикрепленный ниже архив с исходным кодом программ на языке программирования (низкого уровня) Ассемблер, вы сможете одним запуском командного файла собрать приложение.
Ничего не нужно устанавливать и настраивать, всё в одной папке.
Просто распакуйте в любом месте. В ОС современного типа, соберётся одна программа (третья) под именем PrivWin32.

Первая программа COM.
 Развернуть: PrivCom . ASM - программа COM, DOS
Код: Выделить всё
%TITLE "PrivCom.asm"

; Сборка программы:
; tasm PrivCom
; tlink /k PrivCom
; В результате получится COM-программа.

.MODEL TINY
.DATA
msg db 'JPuBET!', 13, 10, 36
.CODE
org 100h
Start:
mov   ax, @data
mov   ds, ax
mov   ah, 9
mov   dx, offset msg
int   21h
mov   ah, 0
int   16h
mov   ax, 4C00h
int   21h
END   Start

Вторая прогамма EXE
 Развернуть: PrivExe . ASM - программа EXE, DOS
Код: Выделить всё
%TITLE "PrivExe.asm"

; Сборка программы:
; tasm PrivExe
; tlink PrivExe
; В результате получится EXE-программа.

.MODEL SMALL
.STACK 256
.DATA
msg db 'JPuBET!', 13, 10, 36
.CODE
Start:
mov   ax, @data
mov   ds, ax
mov   ah, 9
mov   dx, offset msg
int   21h
mov   ah, 0
int   16h
mov   ax, 4C00h
int   21h
END   Start

Третья программа EXE - Windows
 Развернуть: PrivWin32 . ASM - программа EXE, Windows
Код: Выделить всё
%TITLE "PrivWin32.asm"

   IDEAL   ; Переводит Turbo Assembler в режим Ideal.
   P386   ; Разрешение всех инструкций процессора 80386.
   MODEL   flat, STDCALL ; Модель памяти.

   DATASEG ; Сегмент данных.

szAppname   db 'PrivWin32', 0 ; Имя прикладной программы или заголовок
szMessage   db 'Привет - Моя первая программа.', 0 ; Cтрока сообщения.

   CODESEG ; Тело программы (сегмент кода).

global GetModuleHandleA:near ; Импортируемые функции из Windows
global MessageBoxA:near   ; API
global ExitProcess:near   ; (Application Program[ming] Interface).

Start:
   push   0      ; Стандартная процедура
   call   GetModuleHandleA   ; начала приложения.

   push   40h      ; Стиль окна сообщ. "ICON_INFORMATION"
   push   offset szAppname   ; Заголовок окна.
   push   offset szMessage   ; Строка сообщения.
   push   0      ; Идентификатор родительского окна.
   call   MessageBoxA   ; Вызов стандартного окна сообщений.

Exit:
   push   0      ; Код выхода и
   call   ExitProcess   ; завершение программы.

   END   Start   ; Конец программы/точка входа.

В пакете, находятся файлы сборки и компилятор Tasm. Хотя Tasm, вы можете скачать и с главного сайта форума.
Я добавил Tasm для удобства начинающего. Всё готово, стоит лишь запустить BAT-файл...

Образец BAT-сборки под Windows:
 Развернуть: Make_PrivWin32 . BAT - собирает программу EXE 32-битную
Код: Выделить всё
@Echo off

set APPNAME=PrivWin32

set TASM=%~dp0TASM\Bin
set PATH=%TASM%;
set INC=%~dp0TASM\Include
set LIBS=%~dp0TASM\Lib

if not exist %TASM% goto ERROR

Tasm32 /ml /m2 %APPNAME%
if errorlevel 1 goto DOEXIT

Brc32 -r -I%INC% -fo%APPNAME% %APPNAME%.rc
if errorlevel 1 goto DOEXIT

Tlink32 /Tpe /aa /c %APPNAME%.obj, %APPNAME%,, %LIBS%\import32, %APPNAME%.def, %APPNAME%.res
if errorlevel 1 goto DOEXIT
pause
del *.map
del *.obj
del *.res
del *.tr2
del *.td2
goto EXIT

:ERROR
@echo.
@echo.
@echo.   --- ERROR ---
@echo.   Missing %TASM%
@echo.
@echo.   Ћ˜€ЃЉЂ! ЋвбгвбвўгҐв Ї ЇЄ  %TASM%
@echo.

:DOEXIT
pause

:EXIT
Вложения
Privet.zip
(1.94 Мб) Скачиваний: 131
Последний раз редактировалось luzga 07 май 2026, 13:59, всего редактировалось 1 раз.
Аватара пользователя
luzga
Мастер Даунгрейда
 
Сообщения: 320
Зарегистрирован: 04 сен 2025, 19:35

Re: Привет - Моя первая программа

Сообщение inc1001 » 06 май 2026, 14:52

luzga, это же был шуточный привет в качестве первого сообщения :).
Мне больше нравится MASM, сейчас использую версию 6.14.8444.
Что касается текстового стиля (на мой взгляд), табуляция внутри инструкций и капслок замедляет чтение и анализ кода.
В windows программе вызывается GetModuleHandleA, но дескриптор нигде не используется. Зачем?
inc1001
Даунгрейдер
 
Сообщения: 5
Зарегистрирован: 02 фев 2025, 21:36

Re: Привет - Моя первая программа

Сообщение luzga » 06 май 2026, 15:30

inc1001 писал(а):это же был шуточный привет в качестве первого сообщения

Вы хотели показать, что знаете, что-то?
Таким /, вся сеть наполнена. Сорри, но по-другому не скажешь. Толк из вашего кода, ведь так?
inc1001 писал(а):Что касается текстового стиля (на мой взгляд), табуляция внутри инструкций и капслок замедляет чтение и анализ кода.

Это ни на что не влияет, кроме удобства и понятливости!
inc1001 писал(а):В windows программе вызывается GetModuleHandleA, но дескриптор нигде не используется. Зачем?

Это приём. Хакерский.
Аватара пользователя
luzga
Мастер Даунгрейда
 
Сообщения: 320
Зарегистрирован: 04 сен 2025, 19:35

Re: Привет - Моя первая программа

Сообщение StoYazykov » 07 май 2026, 12:51

luzga, а что за хакерский приём с GetModuleHandleA?
Самое тёмное дело - это строки в C


Сайт программистов: http://pmmx166.byethost8.com / http://revival.narod.ws
Аватара пользователя
StoYazykov
Мастер Даунгрейда
 
Сообщения: 199
Зарегистрирован: 25 дек 2023, 11:25
Откуда: Казань
Железо: Intel Pentium MMX 166 MHz, 8 и 2 ГБ HDD, 80 MB RAM; AMD A8-6410 APU with Radeon R5 Graphics, 16 ГБ

Re: Привет - Моя первая программа

Сообщение luzga » 07 май 2026, 13:50

StoYazykov писал(а):что за хакерский приём с GetModuleHandleA?

Смайли ставить обизательно ? :) Юмор, юмор. (ну-и ошибку спец.допустил);
Аватара пользователя
luzga
Мастер Даунгрейда
 
Сообщения: 320
Зарегистрирован: 04 сен 2025, 19:35

Re: Привет - Моя первая программа

Сообщение StoYazykov » 07 май 2026, 21:56

Так что же за приём такой?
P. S. Я (полностью) перешёл на Линух, так что под Винду писать буду меньше.
P. P. S. Появился сайт для исходников программ: http://unixstoyazykov.hostingem.ru/
Последний раз редактировалось StoYazykov 08 май 2026, 00:07, всего редактировалось 1 раз.
Самое тёмное дело - это строки в C


Сайт программистов: http://pmmx166.byethost8.com / http://revival.narod.ws
Аватара пользователя
StoYazykov
Мастер Даунгрейда
 
Сообщения: 199
Зарегистрирован: 25 дек 2023, 11:25
Откуда: Казань
Железо: Intel Pentium MMX 166 MHz, 8 и 2 ГБ HDD, 80 MB RAM; AMD A8-6410 APU with Radeon R5 Graphics, 16 ГБ

Получение IP-адреса.

Сообщение luzga » 08 май 2026, 07:46

На Ассемблере, писать программы сложно, но не из-за сложности как таковой.
Просто, неудобно работать с отладчиком, а он для Tasm, один - Turbo Debugger.
В любом случае, здесь будет несколько программ, может и больше...
Чтобы программа делала, что-то полезное, напишем утилиту Получение IP-адреса.

Прежде всего, нужно оборудовать среду разработки.
Внести путь компилятора в список переменных ОС.
В современных ОС, сейчас уже нет файла Autoexec.bat, в нём располагался
список.
Как же быть? Можно в корне диска ОС, создать в Блокноте (Notepad)
вызвав нажатием Win+R, напечатать Notepad %SystemDrive%\Autoexec.bat
Если файла нет, система спросит: - Cоздать файл с именем Autoexec?
Нужно заключить имя файла в кавычки, добавив расширение BAT и сохранить.
Добавим путь Tasm в переменную Path:
Path=C:\Tasm\Bin
Если переменная Path уже есть? Тогда добавить новое значение через точку с запятой.
 Развернуть: Пример моего Autoexec.bat
@Echo Off

Path=C:\BC5\Bin;C:\Bin;C:\Bin\Dos;C:\Tasm\Bin

@C:\Bin\Dos\mode con codepage prepare=((866) C:\Bin\Dos\Ega3.cpi)
@C:\Bin\Dos\mode con codepage select=866
@C:\Bin\Dos\keyb ru,,C:\Bin\Dos\Keybrd3.sys

IF "%config%"=="IDLE" goto SKIP

call Empty

:SKIP

Чтобы изменения вступили в силу, нужно перезагрузить компьютер.
Такой способ применяется для компьютеров работающих под ДОС.
В Windows настройка списка переменных делается так:
нажать сочетание клавиш Win+R и ввести команду: SYSDM.cpl
Этим вызывается Свойства системы, сродни нажатию правой клавишей мыши по-значку Мой Компьютер.
Нужно открыть вкладку Дополнительно и перейти на Переменные среды.
В Переменных среды, нужно, если нет переменной Path (в самом верху),
создать и добавить значение, а если есть, добавить через точку с запятой.
 Развернуть: Переменные среды
Изображение

После всех изменений, для проверки, открыть консоль Win+R, команда:
cmd /k
аргумент k добавлен для того, чтобы консоль не закрылась, так было раньше
в версиях Windows XP до сервис пак 3 (SP3). Нажимаешь или вводишь cmd
и всё, закрылось...
В открывшейся консоли, ввести команду: Tasm
Должен быть результат вывода подсказки о работе Tasm или, в случае неверных натроек, сообщение о том, что не найдена команда.
 Развернуть: Результат команды Tasm
Изображение

Ваша задача, настроить переменные среды!

Я постарался описать некоторые детали т.е. читайте комментарий в коде программы. Также. Большую помощь оказывает Гугл, если задать вопрос
вида Tasm CreateFileA() пример - получите информацию!
 Развернуть: GetIP.asm
Код: Выделить всё
%TITLE "GetIP.asm"
;-------------------------------------------------------
; Программа подключается к сайту checkip.dyndns.org
; по-протоколу HTTP. Скачивает страницу "Current IP Check.htm".
; Сохраняет скаченное во-временной директории ОС Windows,
; с именем ip.txt. Копирует адрес в Буфер Обмена
; выводит информацию и завершается.
; Программа работает в ОС Windows.
;-------------------------------------------------------
   IDEAL   ; Переводит Turbo Assembler в режим Ideal.
   P386   ; Разрешение всех инструкций процессора 80386.
   MODEL   flat, STDCALL ; Модель памяти.

   DATASEG ; Сегмент данных.
;-------------------------------------------------------
szAppname db 'GetIP', 0 ; Имя (заголовок) программы

; urlmon.dll модуль библиотеки ОС
szLibFileName db 'urlmon',0
; Имя функции
szProcName db 'URLDownloadToFileA',0

; Страница, которую программа, попробует загрузить.
szUrl db 'http://checkip.dyndns.org/Current IP Check.htm',0
; Имя файла в котором будет сохранена страница.
szName db 'ip.txt',0

; Информационные сообщения.
szFormat db 'IP-адрес компьютера: %s', 0
szFormat2 db 'IP-адрес компьютера: %s', 13, 10, 13, 10
db 'Адрес скопирован в Буфер Обмена', 13, 10
db 'для вставки в документ нажмите клавишу "Ctrl+V".',0

; Сообщения о неудачах.
szErr1 db 'Не удалось загрузить функцию URLDownloadToFile',0
szErr2 db 'Нет связи.',0
szErr3 db 'Не удалось создать временный файл для записи.',0
szError db 'Нет ', 0
szFailed db 'Не удалось', 0

; Другие переменные.
szSkobka db '<',0

szTempFileName   db 104h   dup(0) ; MAX_PATH = 260
szBuff      db 400h   dup(0) ; 1024
szResult   db 400h   dup(0) ; 1024

pURLDownloadToFile dd 0
hModule      dd 0
hFile      dd 0 ; Дескриптор файла
szToken      dd 0
dwBytesRead   dd 0
nLen      dd 0

   CODESEG ; Тело программы (сегмент кода).
;-------------------------------------------------------
; Список процедур экспортируемых из ОС.
include "AProc.inc" ; Отдельный файл, для удобства.
;-------------------------------------------------------
Start:
   ; Загрузка функции URLDownloadToFile
   ; из библиотечного модуля urlmon.dll
   push offset szProcName
   push offset szLibFileName
   call LoadLibraryA
   ; Получить адрес функции
   push eax ; hModule
   call GetProcAddress
   ; Сохранить адрес функции в переменной
   mov [pURLDownloadToFile], eax
   ; Адрес функции получен, если регистр EAX не нуль
   ; продолжить программу или сообщить о ошибке и выйти из программы.
   cmp eax, 0
   jne short @@10
   push offset szErr1   ; Отправить сообщение о ошибке и
   call mb ; выйти из программы.
@@10:
   ; Сооружение имени файла в который будет записан
   ; ответ удаленного сервера.
   ; Сначала узнать, где расположен временный каталог системы.
   push offset szTempFileName
   push 104h
   call GetTempPathA

   ; Конкатенации (объединение) двух строк.
   ; имя временного каталога ОС (у меня C:\Temp) с именем файла
   ; C:\Temp и Ip.txt
   push offset szName
   push offset szTempFileName
   call lstrcatA

   ; Вызов функции ОС URLDownloadToFile
   ; скачивает файл из интернета (URL) и сохраняет
   ; его на локальный диск. В нашем случае во временный
   ; каталог ОС с именем Ip.txt (у меня C:\Temp\Ip.txt).
   push 0
   push 0
   push offset szTempFileName
   push offset szUrl
   push 0
   call [pURLDownloadToFile]
   cmp eax, 0
   je short @@20
   
   push offset szErr2   ; Отправить сообщение о ошибке и
   call mb   ; выйти из программы.
@@20:
   ; Открыть записанный файл из временного каталога
   ;
   push 0   ; hTemplateFile Дескриптор файла шаблона
   push 0   ; dwFlagsAndAttributes Атрибуты файла
   push 3   ; dwCreationDisposition Действие (создать/открыть)
   push 0   ; lpSecurityAttributes Атрибуты безопасности
   push 0   ; dwShareMode Режим совместного доступа
   push 80000000h   ; dwDesiredAccess Режим доступа (чтение/запись)
   push offset szTempFileName ; Имя файла/устройства
   call CreateFileA
   mov [hFile], eax ; Дескриптор файла
   cmp eax, 0FFFFFFFFh ; -1
   jne short @@30

   push offset szErr3   ; Отправить сообщение о ошибке и
   call mb   ; выйти из программы.
@@30:
   ; Получить данные из файла в буфер.
   ;
   push 0   ; lpOverlapped Для асинхронного чтения
   push offset dwBytesRead ; lpNumberOfBytesRead Указатель на переменную с числом считанных байт
   push 80h ; nNumberOfBytesToRead Сколько байт прочитать
   push offset szResult ; Буфер для данных
   push [hFile] ; Дескриптор файла
   call ReadFile
   push [hFile]
   call CloseHandle

   ; Разбор данных.
   push 3Ah ; Отсечь строку по двоеточие :
   push offset szResult
   call strrchr
   add esp, 8
   mov [szToken], eax

   push offset szSkobka
   push [szToken]
   call strtok
   add esp, 8
   mov [szToken], eax

   push 400h
   mov eax, [szToken]
   add eax, 2
   push eax ; String
   push offset szResult
   call lstrcpynA
   
   push offset szResult
   call lstrlenA
   mov [nLen], eax
   cmp [nLen], 0
   jz short @@40

   ; Скопировать IP-адрес в Буфер Обмена.
   push offset szResult
   call CopyToClipboard
   mov [nLen], eax
@@40:
   cmp [nLen], 0
   jnz short @@50
   push offset szResult
   push offset szFormat
   push offset szBuff
   call _wsprintfA
   add esp, 0Ch
   jmp short @@99
@@50:
   push offset szResult
   push offset szFormat2
   push offset szBuff
   call _wsprintfA
   add esp, 0Ch
@@99:
   push offset szBuff
   call mb
;Exit:
   push 0
   call ExitProcess   ; Завершение программы.

;-------------------------------------------------------
; Подпрограммы помощники
;-------------------------------------------------------

proc CopyToClipboard
   ARG Str:dword
   USES ebx, edi, esi
   call CloseClipboard
   call GetActiveWindow
   push eax
   call OpenClipboard
   test eax, eax
   jz short @@99
   call EmptyClipboard
   mov ebx, [Str]
   push ebx
   call lstrlenA
   inc   eax
   push eax   ; Bytes
   push 2002h   ; Flags
   call GlobalAlloc
   mov   esi, eax
   test esi, esi
   jz short @@10
   push esi   ; Mem
   call GlobalLock
   mov   ebx, [Str]
   push ebx
   push eax   ; String
   call lstrcpyA
   push esi   ; Mem
   call GlobalUnlock
   push esi   ; Mem
   push 1   ; uFormat
   call SetClipboardData
   test eax, eax
   jz short @@10
   mov   ebx, 1
@@10:
   call CloseClipboard
@@99:
   mov   eax, ebx
   ret
endp CopyToClipboard

proc mb
   ARG   svStr:dword
   USES ebx, edi, esi
   mov   esi, 11040h   ; uType
   xor   ebx, ebx
   push offset szFailed   ; В строке есть слово "Failed"?
   mov   edi, [svStr]
   push edi
   call strstr
   add   esp, 8
   cmp   eax, 0
   jne   short @@10
   push offset szError   ; В строке есть слово "Error"?
   push edi
   call strstr
   add   esp, 8
   cmp   eax, 0
   je short @@20
@@10:
   inc   ebx
@@20:
   cmp   ebx, 0
   je short @@30
   and   esi, 0FFFFFFBFh
   or esi, 30h
@@30:
   push esi      ; uType
   push offset szAppname   ; lpCaption
   push edi      ; lpText
   call GetActiveWindow
   push eax      ; hWnd
   call MessageBoxA
   cmp   ebx, 0
   je short @@99
   push ebx      ; uExitCode
   call ExitProcess
@@99:
   ret
endp mb

   END   Start   ; Конец программы/точка входа.

 Развернуть: Результат
Изображение
Вложения
GetIP.zip
(51.47 Кб) Скачиваний: 120
Последний раз редактировалось luzga 08 май 2026, 14:25, всего редактировалось 1 раз.
Аватара пользователя
luzga
Мастер Даунгрейда
 
Сообщения: 320
Зарегистрирован: 04 сен 2025, 19:35

Netmon

Сообщение luzga » 12 май 2026, 19:51

Программа отображает информацию о сетевом трафике.
Эта программа с просторов интернет. Мне с трудом удалось найти её!
Будет полезна обладателям Windows, начиная с 7 и выше. Думаю, будет работать. Ведь в современных ОС, нет никакой индикации, а это, будет помигивать.
P.S. Эту программу, я встретил давно. Знал о ней все эти годы. Вот подумал, что неплохо бы было выложить её сейчас. Стал искать и нашёл только в архиве. Там небыло исходного кода, только страница сайта. Прошёлся в поиске по многим, чуть ли не всем сохраннёным копиям - ничего.
В конечном итоге, наткнулся на это. Кто-то воссоздал оригинал.
Примеры программ, в основном, применимы к ассемблеру MAsm, но при желании, можно перевести и для TAsm!

 Развернуть: Так выглядит
Изображение

 Развернуть: Netmon.asm
смотрите в пакете
Вложения
Netmon.zip
(59.37 Кб) Скачиваний: 110
Последний раз редактировалось luzga 25 май 2026, 07:59, всего редактировалось 2 раз(а).
Аватара пользователя
luzga
Мастер Даунгрейда
 
Сообщения: 320
Зарегистрирован: 04 сен 2025, 19:35

GetIP - 2

Сообщение luzga » 27 май 2026, 11:41

В этой версии GetIP, есть индикатор прогресс, чтобы не думать:
- запустил ли я, эту программу?

Как это работает?
Программа начинается с создания нового потока виртуального адресного пространства текущего процесса.
Первый этап потока: ожидание появления MessageBox с сообщением (см. ниже).
После того, как поток запущен, запускается системный MessageBox с сообщением:
Подключение к серверу checkip.dyndns.org
Пожалуйста, ждите...
В этот момент, поток обнаруживает системный MessageBox.
Поток, переходит на следующий этап. Вычисляет место для индикатора (Progress Bar) и создаёт его в родительском окне т.е. в MessageBox.
Этот трюк сделан, чтобы не создавать собственное окно.
После этого, происходит индикация происходящего. Если пользователь закроет окно, программа прекращается.
 Развернуть: Анимация GetIP
Изображение

 Развернуть: GetIP.asm
Код: Выделить всё
%TITLE "GetIP.asm"
;-------------------------------------------------------
; Программа подключается к сайту checkip.dyndns.org
; по-протоколу HTTP. Скачивает страницу "Current IP Check.htm".
; Сохраняет скаченное во-временной директории ОС Windows,
; с именем ip.txt. Копирует адрес в Буфер Обмена
; выводит информацию и завершается.
; Программа работает в ОС Windows.
;-------------------------------------------------------
   IDEAL   ; Переводит Turbo Assembler в режим Ideal.
   P386   ; Разрешение всех инструкций процессора 80386.
   MODEL   flat, STDCALL ; Модель памяти.

include   "Win32.inc" ; Содержит структуры, определение переменных.
include   "GetIP.ri" ; Вставка идентификаторов ресурсов.

COLOR_RED equ 0FFh ; Цвет прогресс бара RGB(255, 0, 0) красный.
COLOR_BLUE equ 0FF0000h ; Цвет прогресс бара RGB(0, 0, 255) синий.

nMaxRange equ 100
DEBUG_APP equ 0 ; Для отладки, нужно установить не нуль т.е. единицу.

   DATASEG ; Сегмент данных.
;-------------------------------------------------------
szAppname db 'GetIP - Узнать IP-адреса', 0 ; Имя (заголовок) программы
szMsg db 13,10,'Подключение к серверу checkip.dyndns.org ',13,10
db 'Пожалуйста, ждите...',0

szProgressWnd db 'msctls_progress32',0
szProgressApp db 'Progress',0

; urlmon.dll модуль библиотеки ОС
szLibFileName db 'urlmon',0
; Имя функции
szProcName db 'URLDownloadToFileA',0

; Страница, которую программа, попробует загрузить.
szUrl db 'http://checkip.dyndns.org/Current IP Check.htm',0
; Имя файла в котором будет сохранена страница.
szName db 'ip.txt',0

; Информационные сообщения.
szFormat db 'IP-адрес компьютера: %s',0
szFormat2 db 'IP-адрес компьютера: %s',13,10
db 'Адрес скопирован в Буфер Обмена',13,10
db 'для вставки в документ нажмите клавишу "Ctrl+V".',0
szSkobka db '<',0
szMatch db 'Current IP Address:',0 ; Найти совпадение

; Сообщения о неудачах.
szErr01 db 'Не удалось создать progress bar',0
szErr02 db 'Не удалось загрузить функцию URLDownloadToFile',0
szErr03 db 'Нет связи.',0
szErr04 db 'Не удалось создать временный файл для записи.',0
szErr05 db 'Не удалось. Блокирует Ростелеком!',0
szErrTemp db 'Нет ', 0
szErrTemp2 db 'Не удалось', 0
szDebugFileName db 'ip_dbg.txt',0 ; Для отладки.

   UDATASEG ; Сегмент неинициализированных переменных.

szTempFileName   db 104h dup(?) ; MAX_PATH = 260
szBuff      db 2*400h dup(?) ; 2048
szResult      db 2*400h dup(?) ; 2048

szToken      dd ?
tid      dd ?
hInstance      dd ?
bRunning      dd ?

   CODESEG ; Тело программы (сегмент кода).
;-------------------------------------------------------
; Список процедур экспортируемых из ОС.
include "AProc.inc" ; Отдельный файл, для удобства.
;-------------------------------------------------------

proc   WorkThread
   LOCAL @@pURLDownloadToFile:dword, @@nLen:dword
   LOCAL @@dwBytesRead:dword

   ; Загрузка функции URLDownloadToFile
   ; из библиотечного модуля urlmon.dll
   push offset szProcName
   push offset szLibFileName
   call LoadLibraryA
   ; Получить адрес функции
   push eax ; hModule дескриптор.
   call GetProcAddress
   ; Сохранить адрес функции в переменной
   mov [@@pURLDownloadToFile], eax
   ; Адрес функции получен, если регистр EAX не нуль
   ; продолжить программу или сообщить о ошибке
   ; и выйти из программы.
   cmp eax, 0
   jne short @@10

   push offset szErr02 ; Скопировать в буфер сообщение о ошибке
   push offset szBuff ; и перейти на метку DOEXIT.
   call lstrcpyA
   jmp DOEXIT
@@10:
   ; Сооружение имени файла в который будет записан
   ; ответ удаленного сервера.
   ; Сначала узнать, где расположен временный каталог системы.
   push offset szTempFileName
   push 104h
   call GetTempPathA

   ; Конкатенация (объединение) двух строк:
   ; имя временн. каталога ОС (у меня C:\Temp) с именем файла
   ; C:\Temp и Ip.txt
   push offset szName
   push offset szTempFileName
   call lstrcatA

   ; Вызов функции ОС URLDownloadToFile
   ; скачивает файл из интернет (URL) и сохраняет
   ; его на локальный диск. В нашем случае во временный
   ; каталог ОС с именем Ip.txt (у меня C:\Temp\Ip.txt).
   push 0
   push 0
   push offset szTempFileName
   push offset szUrl
   push 0
   call [@@pURLDownloadToFile]
   cmp eax, 0
   je short @@20

   push offset szErr03 ; Скопировать в буфер сообщение о ошибке
   push offset szBuff ; и перейти на метку DOEXIT.
   call lstrcpyA
   jmp DOEXIT
@@20:
; Открыть записанный файл из временного каталога
   push 0   ; hTemplateFile Дескриптор файла шаблона
   push 0   ; dwFlagsAndAttributes Атрибуты файла
   push 3   ; dwCreationDisposition Действие (создать/открыть)
   push 0   ; lpSecurityAttributes Атрибуты безопасности
   push 0   ; dwShareMode Режим совместного доступа
   push 80000000h   ; dwDesiredAccess Режим доступа (чтение/запись)

if DEBUG_APP
   push offset szDebugFileName ; Для отладки
else
   push offset szTempFileName ; Имя файла/устройства
endif ; end DEBUG_APP

   call CreateFileA
   mov ebx, eax ; Дескриптор файла
   cmp eax, 0FFFFFFFFh ; -1
   jne short @@30

   push offset szErr04 ; Скопировать в буфер сообщение о ошибке
   push offset szBuff ; и перейти на метку DOEXIT.
   call lstrcpyA
   jmp DOEXIT
@@30:
; Получить данные из файла в буфер.
   push 0   ; lpOverlapped Для асинхронного чтения
   lea eax, [@@dwBytesRead]  ; lpNumberOfBytesRead Указатель на переменную с числом считанных байт
   push eax
   push 400h ; nNumberOfBytesToRead Сколько байт прочитать 1024 (400h)
   push offset szResult ; Буфер для данных
   push ebx   ; Дескриптор файла
   call ReadFile
   push ebx
   call CloseHandle

; Проверить, есть совпадение на строку в полученном тексте?
   push offset szMatch
   push offset szResult
   call strstr   ; Если, текст szResult содержит текст szMatch
   add esp, 8 ; то переход на метку @@35 или сообщение и выход
   cmp eax, 0
   jne short @@35

   push offset szErr05 ; Скопировать в буфер сообщение о ошибке
   push offset szBuff ; и перейти на метку DOEXIT.
   call lstrcpyA
   jmp DOEXIT
@@35:
; Разбор данных.
   push 3Ah ; Отсечь строку по двоеточие :
   push offset szResult
   call strrchr
   add esp, 8
   mov [szToken], eax

   push offset szSkobka
   push [szToken]
   call strtok
   add esp, 8
   mov [szToken], eax

   push 400h
   mov eax, [szToken]
   add eax, 2
   push eax ; String
   push offset szResult
   call lstrcpynA

   push offset szResult
   call lstrlenA
   mov [@@nLen], eax
   cmp [@@nLen], 0
   je short @@40

; Скопировать IP-адрес в Буфер Обмена.
   push offset szResult
   call CopyToClipboard
   mov [@@nLen], eax
@@40:
   cmp [@@nLen], 0
   jne short @@50
   push offset szResult
   push offset szFormat
   push offset szBuff
   call _wsprintfA
   add esp, 0Ch
   jmp short @@99
@@50:
   push offset szResult
   push offset szFormat2
   push offset szBuff
   call _wsprintfA
   add esp, 0Ch
@@99:
   jmp DOEXIT
endp   WorkThread

proc   ProgressThread
   LOCAL @@hwnd:dword, @@hwndProgress:dword
   LOCAL @@rect:RECT, @@newPos:dword
   LOCAL @@x:dword, @@y:dword, @@width:dword, @@height:dword

; Найти главное окно программы, в данном случае системный MessageBox.
@@10:
   push 50 ; Таймаут (небольшой перерыв).
   call Sleep ; Используется для приостановки выполнения текущего потока программы на заданный промежуток времени.

; Найти диалоговое окно (системный MessageBox).
   push offset szAppname ; Заголовок окна.
   push 0
   call FindWindowA ; Используется для получения дескриптора (HWND) окна верхнего уровня по его заголовку или имени класса.
   mov [@@hwnd], eax ; Продолжать поиск, пока не найден дескриптор
   cmp eax, 0 ; т.е. регистр eax не нуль.
   je short @@10

; Обеспечивает загрузку библиотеки Comctl32.dll.
   call InitCommonControls

; Скрыть кнопку OK у MessageBox.
   push SW_HIDE
   push [@@hwnd]
   call GetTopWindow
   mov ebx, eax
   push eax
   call ShowWindow

; Вычислить координаты главного окна (т.е. родительского),
; в данном случае, родительское окно, системный MessageBox.
   lea eax, [@@rect]
   push eax
   push [@@hwnd]
   call GetClientRect ; Используется для получения размеров клиентской (рабочей) области окна.
   mov [@@x], 1
   mov edx, [@@rect.bottom]
   add edx, 0FFFFFFECh
   mov [@@y], edx
   mov ecx, [@@rect.right]
   add ecx, 0FFFFFFFEh
   mov [@@width], ecx
   mov [@@height], 20

; Создать прогресс индикатор (Progress Bar).
   push 0      ; lpParam
   push [hInstance]
   push IDC_PROGRESS ; Объявлен в файле GetIP.ri
   push [@@hwnd]   ; hWndParent дескриптор род. окна.
   push [@@height]
   push [@@width]
   push [@@y]
   push [@@x]
   push 50000001h   ; dwStyle
   push offset szProgressApp ; Заголовок окна
   push offset szProgressWnd ; Имя оконного класса msctls_progress32
   push 0      ; dwExStyle
   call CreateWindowExA
   mov [@@hwndProgress], eax
   cmp eax, 0
   jne short @@30
; Не удалось создать прогесс бар
   push offset szErr01 ; Скопировать в буфер сообщение о ошибке
   push offset szBuff ; и перейти на метку DOEXIT.
   call lstrcpyA
   jmp DOEXIT

@@30:
; Создать рабочий поток.
   push offset tid      ; lpThreadId
   push 0         ; dwCreationFlags
   push 0         ; lpParameter
   push offset WorkThread   ; lpStartAddress
   push 0         ; dwStackSize
   push 0         ; lpThreadAttributes
   ; Cоздания нового потока исполнения внутри
   ; виртуального адресного пространства текущего процесса.
   call CreateThread

; Цвет прогресс индикатора.
   push COLOR_RED      ; lParam
   push 0         ; wParam
   push PBM_SETBARCOLOR   ; Msg
   push [@@hwndProgress]
   call SendMessageA

; Показать прогресс индикатор.
   push SW_SHOW
   push [@@hwndProgress]
   call ShowWindow

; Вычислить диапазон прогресс индикатора (0-100).
   mov eax, nMaxRange
   shl eax, 10h
   or eax, 0

; Установить диапазон прогресс индикатора.
   push eax         ; lParam   
   push 0         ; wParam
   push PBM_SETRANGE   ; Msg
   push [@@hwndProgress]
   call SendMessageA
   mov [@@newPos], 0

@@40:
   inc [@@newPos] ; Увеличить индикатор на единицу.
   cmp [@@newPos], nMaxRange ; Если индикатор меньше или равно 100
   jle short @@50 ; не переходить, а
   mov [@@newPos], 0 ; обнулить.

@@50:
; Движение прогресс индикатора.
   push 0         ; lParam
   push [@@newPos]      ; wParam
   push PBM_SETPOS      ; Msg
   push [@@hwndProgress]
   call SendMessageA

   push 20 ; Таймаут. Небольшой переыв.
   call Sleep
   
; Окно видимо, пользователь не закрыл?
   push [@@hwnd]   
   call IsWindowVisible
   cmp eax, 0 ; Сравнить, регистр EAX равен нулю? Если да, выход:
   je short @@90 ; - переход на метку @@99

   cmp [bRunning], 0   ; Если переменная пуста, значит операция
   jne short @@40 ; завершена, выход: - не переходить на метку @@40
@@90:
   push [@@hwndProgress]   ; Закрыть прогресс
   call DestroyWindow

; Закрыть диалоговое окно (MessageBox) нажав кнопку OK.
   push 0         ; lParam
   push 0         ; wParam
   push BM_CLICK      ; Msg
   push ebx
   call SendMessageA      ; Нажать на кнопку OK

; Если буфер не пуст, переход на метку @@99
   cmp [byte szBuff], 0
   jne short @@99
   mov [bRunning], 0 ; иначе, обнулить переменную.
@@99:
   ret
endp   ProgressThread

;
; Начало программы.
;
Start:
   push 0
   call GetModuleHandleA ; Извлекает дескриптор указанного модуля.
   mov [hInstance], eax

; Создать прогресс индикатор (поток).
   push offset tid
   push 0         ; dwCreationFlags
   push 0         ; lpParameter
   push offset ProgressThread   ; lpStartAddress
   push 0         ; dwStackSize
   push 0         ; lpThreadAttributes
   ; Cоздания нового потока исполнения внутри
   ; виртуального адресного пространства текущего процесса.
   call CreateThread

   mov [bRunning], 1 ; Работа началась, установить флаг.
   push offset szMsg ; Вместо диалогового окна, вызовем системный
   call mb ; MessageBox. В созданном ранее, потоке ProgressThread
   pop ecx ; получим дескриптор и станем работать как с собственным.
   ; Способ таит подводные камни, нужно пользоваться осторожно.

; Обработка сообщений: у нас не собственное окно, станем ждать завершения
; процесса, контролируя переменную. Когда bRunning обнулится,
; значит работа окончена. Следует переход на метку Exit, что завершит программу.
@@99:
   push 20
   call Sleep
   cmp [bRunning], 1
   je short @@99
   jmp short Exit

DOEXIT:
; Найти и закрыть окно с прогресс баром.
   push offset szAppname ; Заголовок окна.
   push 0
   call FindWindowA
   cmp eax, 0
   je short Exit
   push eax
   call GetTopWindow
   push 0      ; lParam
   push 0      ; wParam
   push BM_CLICK   ; Msg
   push eax
   call SendMessageA   ; Нажать на кнопку OK

; Если переменная szBuff не пуста, значит есть сообщение, вывести.
   cmp [byte szBuff], 0
   je short Exit
   push offset szBuff   ; Отправить сообщение о ошибке и
   call mb   ; выйти из программы.
Exit:
   push 0
   call ExitProcess   ; Завершение программы.

;-------------------------------------------------------
; Подпрограммы помощники
;-------------------------------------------------------

proc CopyToClipboard
   USES ebx, edx, edi, esi
   ARG @@str:dword
   call CloseClipboard
   call GetActiveWindow
   push eax
   call OpenClipboard
   cmp eax, 0
   je short @@99
   mov edx, 0
   call EmptyClipboard
   mov ebx, [@@str]
   push ebx
   call lstrlenA
   inc eax
   push eax   ; Bytes
   push 2002h ; Flags
   call GlobalAlloc
   mov esi, eax
   cmp eax, 0
   je short @@10
   push esi   ; Mem
   call GlobalLock
   mov ebx, [@@str]
   push ebx
   push eax   ; String
   call lstrcpyA
   push esi   ; Mem
   call GlobalUnlock
   push esi   ; Mem
   push 1   ; uFormat
   call SetClipboardData
   cmp eax, 0
   je short @@10
   mov edx, 1
@@10:
   call CloseClipboard
   mov eax, edx
@@99:
   ret
endp CopyToClipboard

proc    mb
   ; Функция выведет сообщение.
   ; Если строка содержит текст, который определён в двух переменных
   ; szErrTemp и szErrTemp2 - это "Нет" и "Не удалось", то функция, после
   ; сообщения, завершает программу.
   USES ebx, edi, esi ; Используются регистры
   ARG @@str:dword ; Строка сообщения
; uType MessageBox (IconInformation)
   mov esi, MB_OK or MB_ICONINFORMATION or MB_SETFOREGROUND or MB_SYSTEMMODAL
   mov ebx, 0
   push offset szErrTemp ; Строка содержит слово "Нет" ?
   mov edi, [@@str]
   push edi
   call strstr ; Используется для поиска первого вхождения
      ; подстроки в другую строку (главную).
   add esp, 8
   cmp eax, 0
   jne short @@10
   push offset szErrTemp2   ; Строка содержит слово "Не удалось" ?
   push edi
   call strstr
   add esp, 8
   cmp eax, 0
   je short @@20
@@10:
   inc ebx
@@20:
   cmp ebx, 0
   je short @@30
; Изменить стиль MessageBox (IconWarning)
   and esi, 0FFFFFFBFh ; MB_OK or MB_ICONWARNING or MB_SETFOREGROUND or MB_SYSTEMMODAL
   or esi, 30h
@@30:
   push esi ; uType MessageBox
   push offset szAppname ; Заголовок окна
   push edi ; Текст сообщения
   call GetActiveWindow ; Извлекает дескриптор (HWND) активного
         ; окна, которое принадлежит очереди
         ; сообщений вызывающего потока.
   push eax ; hWnd, дескриптор родительского окна (может быть нуль)
   call MessageBoxA
   cmp ebx, 0
   je short @@99
   push ebx ; Код выхода для всех потоков.
   call ExitProcess ; Заканчивает работу процесса и всех его потоков.
@@99:
   ret
endp    mb

   END   Start   ; Конец программы/точка входа.

P.S. Внесены изменения. Исправлены неточности.
Вложения
GetIP.zip
(16 Кб) Скачиваний: 58
Последний раз редактировалось luzga 27 май 2026, 17:52, всего редактировалось 3 раз(а).
Аватара пользователя
luzga
Мастер Даунгрейда
 
Сообщения: 320
Зарегистрирован: 04 сен 2025, 19:35

Re: Привет - Моя первая программа

Сообщение luzga » 27 май 2026, 18:03

Есть идея сделать туториал в виде анимации с отладчиком Turbo Degugger.
Последний раз редактировалось luzga 28 май 2026, 05:38, всего редактировалось 1 раз.
Аватара пользователя
luzga
Мастер Даунгрейда
 
Сообщения: 320
Зарегистрирован: 04 сен 2025, 19:35

Re: Привет - Моя первая программа

Сообщение uav » 27 май 2026, 19:11

luzga писал(а):Сохранил результат ранее загруженный и после загрузки кагбы с сайта, открывал не блокировку Ростелеком

На всякий случай поясню, что речь не про блокировки РКН, они тут не при чём, а про то, что Ростелеком чудит с HTTP на вполне "добропорядочных" сайтах, вот тут про это писали:
viewtopic.php?p=39132#p39132
Вообще, по-хорошему, за такое на Ростелеком надо в РКН жаловаться...
Последний раз редактировалось uav 27 май 2026, 19:12, всего редактировалось 1 раз.
Аватара пользователя
uav
Мастер Даунгрейда
 
Сообщения: 3050
Зарегистрирован: 22 дек 2008, 14:21

Re: Привет - Моя первая программа

Сообщение clihlt » 28 май 2026, 06:31

uav писал(а):Вообще, по-хорошему, за такое на Ростелеком надо в РКН жаловаться...
Что останавливает?
С уважением,
Владислав Васильев (aka clihlt).
Аватара пользователя
clihlt
Мастер Даунгрейда
 
Сообщения: 508
Зарегистрирован: 20 мар 2023, 21:17
Откуда: Брянск, СССР

Re: Привет - Моя первая программа

Сообщение luzga » 28 май 2026, 07:11

clihlt, вам действительно невдомёк или вы с издёвкой (я с долей юмора говорю). Неужто не знаете, ... Поэтому, ни-что, не из-ме-ни-т-ся (в квадрате)!
Последний раз редактировалось luzga 28 май 2026, 10:28, всего редактировалось 6 раз(а).
Аватара пользователя
luzga
Мастер Даунгрейда
 
Сообщения: 320
Зарегистрирован: 04 сен 2025, 19:35

Re: Привет - Моя первая программа

Сообщение clihlt » 28 май 2026, 10:01

luzga писал(а):clihlt, вам действительно невдомёк или вы с издёвкой
Конечно же невдомёк -- я ведь ещё не вышел из нежного возраста, в девяностых не жил и "бизнесом" в те прекраснопамятные года не занимался. Ужас какой! Неужели всё, что Вы тут описали действительно существует в нашем чистом и светлом мире розовых пони? Невообразимо! Это наносит травму моей нежной детской психике! Нет, не могу, пойду, приму триста капель эфирной валерьянки. ;)
Последний раз редактировалось clihlt 28 май 2026, 10:02, всего редактировалось 1 раз.
С уважением,
Владислав Васильев (aka clihlt).
Аватара пользователя
clihlt
Мастер Даунгрейда
 
Сообщения: 508
Зарегистрирован: 20 мар 2023, 21:17
Откуда: Брянск, СССР

Re: Привет - Моя первая программа

Сообщение luzga » 28 май 2026, 10:33

clihlt писал(а):приму триста капель эфирной валерьянки.

Не советую. Хотя, кто-то живёт ради выпивки. Работает даже, чтобы в пятницу нажраться и всю субботу в коматозе провести. К-ха-ха-ха.
Да, а если про лекарственные препараты, то тоже - ну-их на фиг! Я забыл, когда таблетку пил и не собираюсь. Вообще, дохкторов придумали шарлатаны. От них никакой пользы. Нужно вести трезвый образ жизни, физкультурой заниматься, не сидет в три погибели играя в глупые игры. Тогда, всё будет хорошо. Доктор нужен, если ты не дай Бог сломал что-то или - в общем чисто физический урон. Остальное, сам себя обязан лечить. Во всяком случае, я так живу.
Аватара пользователя
luzga
Мастер Даунгрейда
 
Сообщения: 320
Зарегистрирован: 04 сен 2025, 19:35

След.

Вернуться в Программирование

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 1