блог-форум о программировании

Вы не вошли.

#1 2021-12-13 22:44:56

Majestio
Администратор
Здесь с 2017-11-17
Сообщений: 93
Windows 10Chrome 88.0

Вспоминая ассемблер


Вспоминая ассемблер


На одном из форумов просто ради интереса написал на fasm'е аналог unix-овской утилиты time.
Получилась красивая нежирная программка, всего 3072 байта:

format PE console
entry start
 
; *****************************************************************************
; timer.exe  - Утилита замера времени исполнения программы, задаваемой в
;              командной строке. fasm 1.73.22
;
;              Copyleft (L) 2020 Majestio AKA JoeUser = http://majestio.info
;
; *****************************************************************************
;          Если командная строка содержит пробелы - ее записываем в кавычках!
;
; *****************************************************************************
 
include 'win32wx.inc'
 
;=======================================
section '.data' data readable writeable
;=======================================
 
argstr   TCHAR 13,10,'Launch: "%s" ... ',13,10,13,10,0
usagestr TCHAR 13,10,'Usage: timer.exe <"cmd">',13,10,0
okstr    TCHAR 13,10,'Done : %.5f sec',13,10,0
erstr    TCHAR 13,10,'Error (%d)!',13,10,0
 
;=======================================
section '.bss' data readable writeable
;=======================================
 
SystemInfo STARTUPINFO
ProcessInfo PROCESS_INFORMATION
 
argc     dd 0       ; количество аргументов командной строки
argv     dd 0       ; ссылка на
cnt1     dq 0       ; счетчик начала
cnt2     dq 0       ; счетчик завершения
freq     dq 0       ; делитель частоты
 
;=======================================
section '.code' code readable executable
;=======================================
 
start:
      invoke GetCommandLineW
      invoke CommandLineToArgvW, eax, addr argc
      mov [argv], eax
      ; проверяем, что аргумент ровно один ARGV[1] (ARGV[0] есть всегда)
      mov eax,[argc]
      cmp eax,2
      jne usage
      ; заносим в argv - ARGV[1]
      mov eax, [argv]
      mov eax, [eax+4]
      mov [argv], eax
      ; Печатаем название запускаемой программы
      invoke wprintf, argstr, [argv]
      mov [SystemInfo.cb],sizeof.STARTUPINFO
      invoke GetStartupInfoW, SystemInfo
      or  [SystemInfo.dwFlags],STARTF_USESHOWWINDOW
      mov [SystemInfo.wShowWindow],SW_HIDE
      ; Чекаем таймер
      invoke QueryPerformanceFrequency, addr freq
      test eax, eax
      jnz @f
      mov eax,  1;  Error 1
      jmp error
@@:   invoke QueryPerformanceCounter, addr cnt1
      test eax, eax
      jnz @f
      mov eax,  2;  Error 2
      jmp error
      ; Запускаем процесс
@@:   invoke CreateProcess,0,[argv],NULL,NULL,FALSE,NORMAL_PRIORITY_CLASS,NULL,NULL,SystemInfo,ProcessInfo
      test eax,eax
      jnz @f
      mov eax,  3;  Error 3
      jmp error
      ; ждем завершения процесса
@@:   invoke WaitForSingleObject, [ProcessInfo.hProcess], -1
      cmp eax, 0xFFFFFFFF
      jne @f
      mov eax,  4;  Error 4
      jmp error
      ; Закрываем хендлы
@@:   invoke CloseHandle, [ProcessInfo.hProcess]
      test eax,eax
      jnz @f
      mov eax,  5;  Error 5
      jmp error
@@:   invoke CloseHandle, [ProcessInfo.hThread]
      test eax,eax
      jnz @f
      mov eax,  6;  Error 6
      jmp error
      ; Чекаем таймер
@@:   invoke QueryPerformanceCounter, addr cnt2
      test eax,eax
      jnz @f
      mov eax,  7;  Error 7
      jmp error
      ; Считаем время
@@:   finit
      fild     qword [cnt2]
      fild     qword [cnt1]
      fsubp
      fild     qword [freq]
      fdivp
      fstp     qword [cnt1]
      ; Выводим время в секундах в виде double:qw
      invoke wprintf, okstr, dword[cnt1], dword[cnt1+4]
      jmp exit
usage:
      invoke wprintf, usagestr
      jmp exit
error:
      invoke wprintf, erstr, eax
exit:
      invoke ExitProcess, 0
 
;====================================
section '.idata' import data readable
;====================================
 
library kernel,'kernel32.dll',\
       shell32,'shell32.dll',\
       msvcrt,'msvcrt.dll'
 
import  kernel,\
       QueryPerformanceFrequency,'QueryPerformanceFrequency',\
       QueryPerformanceCounter,'QueryPerformanceCounter',\
       CloseHandle,'CloseHandle',\
       GetStartupInfoW,'GetStartupInfoW',\
       WaitForSingleObject,'WaitForSingleObject',\
       ExitProcess,'ExitProcess',\
       CreateProcess,'CreateProcessW',\
       GetCommandLineW,'GetCommandLineW'
 
import  shell32,\
       CommandLineToArgvW,'CommandLineToArgvW'
 
import  msvcrt,\
       wprintf,'wprintf'

Вне форума

Сейчас в этой теме пользователей: 0, гостей: 1
[Bot] CCBot

Подвал форума

Под управлением FluxBB
Модифицировал Visman

[ Сгенерировано за 0.049 сек, 8 запросов выполнено - Использовано памяти: 2.4 Мбайт (Пик: 2.72 Мбайт) ]