Blog. Just Blog

Быстрый поиск

Введите фрагмент названия статьи для поиска

Вывод QWORD в виде десятичного числа

05.10.2008 | Категория: Образ мышления: Assembler | Автор: ManHunter
Для преобразования и форматированного вывода 32-битных значений в ассемблере используется стандартная API-функция wsprintf, но она бесполезна при работе с большими числами, например QWORD (64 бита). Значит обойдемся совсем без использования API.
  1. ;---------------------------------------------------
  2. ; Преобразование QWORD в десятичное число
  3. ; Параметры вызова:
  4. ; dwHigh - Старшее двойное слово
  5. ; dwLow  - Младшее двойное слово
  6. ; lpBuff - указатель на буфер-приемник
  7. ;---------------------------------------------------
  8. proc    bignum dwHigh:DWORD, dwLow:DWORD, lpBuff:DWORD
  9.         pushad                   ; Сохранить все регистры
  10.         mov     eax,[dwLow]      ; Младшее двойное слово
  11.         mov     edx,[dwHigh]     ; Старшее двойное слово
  12.         mov     edi,[lpBuff]     ; Указатель на буфер-приемник
  13.  
  14.         xchg    esi,edx          ; Сохранить старший dword
  15.         mov     ebx,10           ; Основание системы счисления
  16.         xor     ecx,ecx          ; Счетчик десятичных цифр
  17. .bignum_1:
  18.         xchg    eax,esi          ; Расчитать десятичную цифру
  19.         xor     edx,edx
  20.         div     ebx
  21.         xchg    esi,eax
  22.         div     ebx
  23.         or      dl,'0'           ; Преобразовать результат в символ цифры
  24.         push    edx              ; Сохранить цифру в стеке
  25.         inc     ecx              ; Увеличить счетчик цифр
  26.         or      eax,eax          ; Все преобразовали?
  27.         jnz     .bignum_1
  28.  
  29. .bignum_2:
  30.         pop     eax              ; Записать все цифры из стека в буфер
  31.         stosb
  32.         loop    .bignum_2
  33.         xor     eax,eax          ; Признак окончания строки
  34.         stosb
  35.         popad                    ; Восстановить все регистры
  36.         ret                      ; Ворзврат из процедуры
  37. endp
Пример использования:

Читать статью целиком »
Просмотров: 9906 | Комментариев: 4

Готовим хреновину

03.10.2008 | Категория: А еще я туда ем! | Автор: ManHunter

Готовим хреновину

Сегодня я расскажу рецепт замечательной острой закуски. Тем более скоро зима, и организму обязательно нужны дополнительные витамины. В каждой семье эта закуска называется по-своему - "огонек", "горлодер" и даже "аджика". Я не буду оспаривать правильность названия, в моей семье это блюдо называется "хреновина".

Читать статью целиком »
Просмотров: 58808 | Комментариев: 50

Время непрерывной работы (Uptime) Windows

01.10.2008 | Категория: Образ мышления: Assembler | Автор: ManHunter
Для получения времени непрерывной работы системы обычно используется функция API GetTickCount. Она возвращает количество миллисекунд, прошедших с момента последнего старта системы. Проблема в том, что счетчик имеет тип dword, и по прошествии примерно 50 дней (49,7 если быть точным) достигает предельного значения и обнуляется. Конечно, продержать систему без перезагрузки почти два месяца трудно, но не значит что невозможно. Поэтому для получения гарантированно точного времени работы системы воспользуемся функцией NtQuerySystemInformation. Достаточно долго эта функция относилась к разряду недокументированных, теперь же на MSDN по ней имеется описание с примечанием, что ее использование в прикладных программах все равно нежелательно.
  1. ; Сегмент данных
  2. section '.data' data readable writeable
  3.  
  4. ; По умолчанию структура в FASM не определена, сделаем это самостоятельно
  5. ; Для получения необходимой информации нужны только два первых значения
  6. struct SYSTEM_TIME_INFORMATION
  7.        liKeBootTime       dq ?  ; Время старта системы
  8.        liKeSystemTime     dq ?  ; Текущее время
  9.        liExpTimeZoneBias  dq ?
  10.        uCurrentTimeZoneId dd ?
  11.        dwReserved         dw ?
  12. ends
  13.  
  14. SystemTime   SYSTEM_TIME_INFORMATION  ; Наша структура с данными
  15.  
  16. ; Константа нужного класса информации тоже не определена, сделаем это сами
  17. GET_SYSTEM_TIME_INFORMATION = 3 
  18.  
  19. ; Сегмент кода
  20. section '.code' code readable executable
  21. ...
  22.         invoke  NtQuerySystemInformation, GET_SYSTEM_TIME_INFORMATION,\
  23.                 SystemTime, sizeof.SYSTEM_TIME_INFORMATION, 0
  24.         ; Записать в регистры EDX:EAX текущее время в миллисекундах
  25.         mov     eax, dword [SystemTime.liKeSystemTime]
  26.         mov     edx, dword [SystemTime.liKeSystemTime+4]
  27.         ; Вычесть время старта системы
  28.         sub     eax, dword [SystemTime.liKeBootTime]
  29.         sbb     edx, dword [SystemTime.liKeBootTime+4]
  30.         ; Теперь в регистры EDX:EAX записано реальное количество миллисекунд,
  31.         ; прошедшее с момента старта системы
  32. ...
Преобразовать миллисекунды в обычный вид даты и времени можно при помощи пары стандартных функций FileTimeToLocalFileTime и FileTimeToSystemTime.

Читать статью целиком »
Просмотров: 6132 | Комментариев: 1

Поиск строки в памяти с использованием маски

29.09.2008 | Категория: Образ мышления: Assembler | Автор: ManHunter
Для поиска произвольной строки в блоке памяти с использованием бинарной маски я написал следующую процедуру:
  1. ; ---------------------------------------------
  2. ; Процедура поиска строки в блоке памяти
  3. ; (C) ManHunter / PCL
  4. ; ---------------------------------------------
  5. ; SRCdata - блок памяти в котором выполняется поиск
  6. ; SRCsize - размер блока в котором выполняется поиск
  7. ; PTRdata - строка для поиска
  8. ; PTRsize - длина строки для поиска
  9. ; MSKdata - бинарная маска для поиска или 0 если не используется
  10. ;
  11. ; Возврат: EAX = offset найденной строки
  12. ;          EAX = -1 если ничего не найдено
  13. ; ---------------------------------------------
  14.  
  15. proc scanmem SRCdata:dword, SRCsize:dword, PTRdata:dword,\
  16.              PTRsize:dword, MSKdata:dword
  17.  
  18.         push    esi edi ebx ecx edx
  19.  
  20.         ; Длина паттерна больше длины данных?
  21.         mov     eax,[PTRsize]
  22.         cmp     eax,[SRCsize]
  23.         ; Да, возврат -1
  24.         ja      .scanmem_not_found
  25.  
  26.         mov     esi,[SRCdata]
  27.         mov     edi,[PTRdata]
  28.         mov     edx,[MSKdata]
  29.         mov     ebx,esi
  30.         add     ebx,[SRCsize]
  31.         sub     ebx,[PTRsize]
  32. .scanmem_loop:
  33.         xor     ecx,ecx
  34. .scanmem_test_char:
  35.         or      edx,edx
  36.         jz      .scanmem_no_mask
  37.         cmp     byte [edx+ecx],0
  38.         jz      .scanmem_char_equal
  39.  
  40. .scanmem_no_mask:
  41.         mov     al,[esi+ecx]
  42.         cmp     al,[edi+ecx]
  43.         jne     .scanmem_next_pattern
  44. .scanmem_char_equal:
  45.         inc     ecx
  46.         cmp     ecx,[PTRsize]
  47.         jb      .scanmem_test_char
  48.         jmp     .scanmem_found
  49. .scanmem_next_pattern:
  50.         inc     esi
  51.         cmp     esi,ebx
  52.         jbe     .scanmem_loop
  53.  
  54. .scanmem_not_found:
  55.         ; Строка не найдена
  56.         mov     eax,-1
  57.         jmp     .scanmem_ret
  58.  
  59. .scanmem_found:
  60.         ; Строка найдена
  61.         mov     eax,esi
  62.  
  63. .scanmem_ret:
  64.         pop    edx ecx ebx edi esi
  65.  
  66.         ret
  67. endp
Пример использования процедуры:

Читать статью целиком »
Просмотров: 7098 | Комментариев: 5

Подсчет времени генерации страницы сайта

25.09.2008 | Категория: Web-мастеру и не только | Автор: ManHunter
Очевидно, что время генерации страницы - это разница от момента обработки первой строчки скрипта до момента обработки последней строчки. Для его расчета точности функции time() недостаточно, так как ее шаг равен 1 секунде. Страница же на сервере обычно генерируется за меньшее время. Если это не так, то стоит всерьез озадачиться оптимизацией вашего кода или сменой хостинг-провайдера. Для замеров более коротких интервалов времени в PHP существует функция microtime(). Она возвращает в виде строки текущее время с микросекундами, например:

0.57975400 1222376863

Значит для подсчета времени требуется получить значения microtime() в начале и конце работы скрипта и отобразить разницу между ними. Для выделения из строки числовых значений воспользуемся функцией explode().
  1. <?
  2. // Начало скрипта
  3.  
  4. // Получаем текущее время с микросекундами
  5. $mtime=explode(" ",microtime());
  6. // После выполнения команды explode() массив $mtime содержит значения:
  7. // $mtime[0] - микросекунды, $mtime[1] - секунды
  8. $tstart=$mtime[1]+$mtime[0]; // Засекаем начальное время
  9.  
  10. ...
  11. ...
  12. // Основной код скрипта
  13. ...
  14. ...
  15.  
  16. // Получаем текущее время с микросекундами
  17. $mtime=explode(" ",microtime());
  18. // Уже знакомая нам функция explode()
  19. $tend=$mtime[1]+$mtime[0]; // Засекаем конечное время
  20. // Округляем до двух знаков после запятой
  21. $totaltime=round(($tend-$tstart),2);
  22. // Результат на экран
  23. echo "Время генерации страницы: ".$totaltime." сек.";
  24.  
  25. // Конец скрипта
  26. ?>
Рабочий пример вы можете посмотреть в самом низу этого сайта.

Читать статью целиком »
Просмотров: 8615 | Комментариев: 5

Наверх
Powered by PCL's Speckled Band Engine 0.2 RC3
© ManHunter / PCL, 2008-2024
При использовании материалов ссылка на сайт обязательна
Время генерации: 0.14 сек. / MySQL: 2 (0.0516 сек.) / Память: 4.5 Mb
Наверх