Blog. Just Blog

Образ мышления: Assembler

То, что не удается запрограммировать на Ассемблере, приходится паять
Образ мышления: Assembler - RSS-канал Образ мышления: Assembler - Карта сайта

Рекурсивный обход дерева каталогов

19.01.2009 | Категория: Образ мышления: Assembler | Автор: ManHunter

Рекурсивный обход дерева каталогов

Обход дерева каталогов является одной из классических прикладных задач на применение рекурсии. В Windows штатных API-функций для этого нет, поэтому поиск файлов выполняется при помощи пары API-функций FindFirstFile и FindNextFile. Совершенно непонятно, почему разработчики Windows не дали возможность точно настраивать критерии поиска, ограничившись только маской имени файла. Даже в MS-DOS для решения аналогичной задачи можно было задать по крайней мере атрибуты файлов, например для поиска только каталогов. Более расширенные возможности для поиска предоставляет API-функция FindFirstFileEx, но она доступна только в операционной системе Windows 2000 и выше.

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

Функции base64 на Ассемблере

09.01.2009 | Категория: Образ мышления: Assembler | Автор: ManHunter
Алгоритм Base64 может использоваться в пользовательских почтовых приложениях, в качестве одного из уровней защиты шифрованием, для хранения двоичных данных и для решения многих других задачах. В большинстве языков высокого уровня используются штатные функции, в Ассемблере приходится все реализовывать самостоятельно.

Алгоритм Base64 обратимый, то есть из закодированного текста можно в точности получить исходные данные. Начнем с функции кодирования.
  1. ;---------------------------------------------------------------
  2. ; Функция кодирования Base64
  3. ;---------------------------------------------------------------
  4. ; Параметры:
  5. ; lpFrom - указатель на исходные данные
  6. ; lpTo   - указатель на буфер для приема кодированных данных
  7. ; dSize  - размер исходных данных
  8. ; Функция ничего не возвращает
  9. ;---------------------------------------------------------------
  10. proc    base64_encode lpFrom:dword, lpTo:dword, dSize:dword
  11.         pusha
  12.  
  13.         mov     ebx,.base64
  14.         mov     esi,[lpFrom]
  15.         mov     edi,[lpTo]
  16.         mov     ecx,[dSize]
  17.  
  18.         or      ecx,ecx
  19.         jz      .r3
  20. .encode_loop:
  21.         lodsd
  22.         mov     edx,eax
  23.         bswap   edx
  24.         xor     eax,eax
  25.  
  26.         shld    eax,edx,6
  27.         shl     edx,6
  28.         xlatb
  29.         stosb
  30.  
  31.         xor     eax,eax
  32.         shld    eax,edx,6
  33.         shl     edx,6
  34.         xlatb
  35.         stosb
  36.         dec     ecx
  37.         jz      .r2
  38.  
  39.         xor     eax,eax
  40.         shld    eax,edx,6
  41.         shl     edx,6
  42.         xlatb
  43.         stosb
  44.         dec     ecx
  45.         jz      .r1
  46.  
  47.         xor     eax,eax
  48.         shld    eax,edx,6
  49.         shl     edx,6
  50.         xlatb
  51.         stosb
  52.  
  53.         dec     esi
  54.         dec     ecx
  55.         jnz     .encode_loop
  56.  
  57.         jmp     .r3
  58. .r2:
  59.         mov     al,'='
  60.         stosb
  61. .r1:
  62.         mov     al,'='
  63.         stosb
  64. .r3:
  65.         xor     eax,eax
  66.         stosb
  67.         popa
  68.  
  69.         ret
  70.  
  71. .base64 db 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
  72.         db 'abcdefghijklmnopqrstuvwxyz'
  73.         db '0123456789+/'
  74. endp
Параметры вызова: lpFrom - указатель на кодируемые данные, lpTo - указатель на буфер для приема кодированных данных и dSize - размер кодируемых данных. Все параметры обязательные. Размер буфера-приемника должен быть примерно в 1,3 раза больше исходных данных, это обусловлено особенностями алгоритма кодирования.

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

Запрет запуска нескольких копий программы

25.12.2008 | Категория: Образ мышления: Assembler | Автор: ManHunter

Запрет запуска нескольких копий программы

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

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

Задача на применение логических инструкций

16.12.2008 | Категория: Образ мышления: Assembler | Автор: ManHunter
Когда-то кому-то помогал с решением задачи на ассемблере, формулировка задания была такая:


Дан массив из 5 байт. Рассматривая его как массив из восьми 5-битных слов, посчитать количество слов с четным числом единиц в слове.


Алгоритм хитровывернутый, комментарии специально не прописывал, чтобы тупая и ленивая школота не смогла объяснить преподу, откуда взялось такое решение и как оно работает.
  1. ;---------------------------------------------------------------
  2. ; Задача на применение логических инструкций
  3. ;
  4. ; Дан массив из 5 байт. Рассматривая его как массив из восьми
  5. ; 5-битных слов, посчитать количество слов с четным числом
  6. ; единиц в слове.
  7. ;
  8. ; Решение: ManHunter / PCL
  9. ;---------------------------------------------------------------
  10.  
  11. format PE GUI 4.0
  12. entry start
  13.  
  14. include 'win32a.inc'
  15.  
  16. ;---------------------------------------------------------------
  17.  
  18. section '.data' data readable writeable
  19.  
  20. xbytes   db 00111000b ; Данные для задачки, взяты с потолка :)
  21.          db 11111110b
  22.          db 01010101b
  23.          db 00001001b
  24.          db 00000110b
  25.  
  26. mask     db 'Count: %i',13,10,13,10
  27.          db '%i%i%i%i%i - %i%i%i%i%i - %i%i%i%i%i - %i%i%i%i%i',13,10
  28.          db '%i%i%i%i%i - %i%i%i%i%i - %i%i%i%i%i - %i%i%i%i%i',13,10
  29.         db 0
  30.  
  31. title    db 'Solution',0
  32. tmp      rb 100
  33.  
  34. ;---------------------------------------------------------------
  35.  
  36. section '.code' code readable executable
  37. start:
  38.          mov     esi,xbytes+4
  39. loc_1:
  40.          lodsb
  41.          mov     ecx,8
  42. loc_2:
  43.          xor     edx,edx
  44.          test    al,00000001b
  45.          jz      loc_3
  46.          inc     edx
  47. loc_3:
  48.          push    edx
  49.          shr     al,1
  50.          loop    loc_2
  51.  
  52.          dec     esi
  53.          dec     esi
  54.          cmp     esi,xbytes
  55.          jnb     loc_1
  56.  
  57.          xor     eax,eax
  58.          xor     esi,esi
  59. loc_4:
  60.          xor     edi,edi
  61.          mov     ecx,5
  62. loc_5:
  63.          add     edi,[esp+eax*4]
  64.          inc     eax
  65.          loop    loc_5
  66.  
  67.          test    edi,edi
  68.          jz      loc_6
  69.          test    edi,1
  70.          jnz     loc_6
  71.          inc     esi
  72. loc_6:
  73.          cmp     eax,40
  74.          jb      loc_4
  75.  
  76.          invoke  wsprintf,tmp,mask,esi
  77.          add     esp,12+(8*5*4)
  78.  
  79.          invoke  MessageBox,HWND_DESKTOP,tmp,title,MB_OK
  80.          invoke  ExitProcess,0
  81.  
  82. ;---------------------------------------------------------------
  83.  
  84. section '.idata' import data readable writeable
  85.  
  86. library kernel32,"KERNEL32.DLL",\
  87.          user32,"USER32.DLL"
  88.  
  89. include "apia\kernel32.inc"
  90. include "apia\user32.inc"
Исходник и скомпилированный файл прилагаются.

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

Обработка перетаскивания файлов (Drag'n'Drop)

10.12.2008 | Категория: Образ мышления: Assembler | Автор: ManHunter
Если в вашем приложении используется обработка файлов, то кроме открытия через стандартные диалоги выбора файла и каталога, можно получать их из Проводника Windows перетаскиванием. Обработка перетаскивания файлов выполняется в два этапа. При инициализации диалогового окна приложения должна вызываться функция DragAcceptFiles. Параметр функции TRUE разрешает принятие файлов окном, а FALSE его запрещает, так что прием файлов можно регулировать динамически. Непосредственно прием файлов окном выполняется функцией DragQueryFile.
  1. ; Сегмент кода
  2. section '.code' code readable executable
  3.         ... 
  4. ; Процедура обработчика окна
  5. proc DialogProc hwnddlg,msg,wparam,lparam 
  6.         ...
  7.         ; Инициализация окна
  8.         cmp     [msg],WM_INITDIALOG
  9.         je      wminitdialog
  10.         ; Обработка перетаскивания файлов
  11.         cmp     [msg],WM_DROPFILES
  12.         je      wmdropfiles
  13.         ...
  14. wminitdialog:
  15.         ; Разрешить окну принимать файлы
  16.         invoke  DragAcceptFiles,[hwnddlg],TRUE
  17.         jmp     processed
  18.  
  19. wmdropfiles:
  20.         ; Обработка полученных файлов. Функция DragQueryFile возвращает имя
  21.         ; файла с указанным индексом (нумерация индексов начинается с нуля).
  22.         ; Для получения общего количества переданных файлов ее надо вызвать с
  23.         ; индексом равным 0FFFFFFFFh
  24.         invoke  DragQueryFile,[wparam],0FFFFFFFFh,NULL,NULL
  25.         ; В регистре EAX количество переданных файлов
  26.  
  27.         ; Перебрать по очереди все переданные окну файлы
  28.         xor     ecx,ecx
  29. process_file:
  30.         push    ecx eax
  31.         ; Получить имя файла или каталога в буфер fname
  32.         invoke  DragQueryFile,[wparam],ecx,fname,100h
  33.         ...
  34.         ; Тут будет обработчик переданных файлов и каталогов
  35.         ...
  36.         pop     eax ecx
  37.         inc     ecx
  38.         cmp     ecx,eax
  39.         jne     process_file
  40.  
  41.         ; Освободить дескриптор операции
  42.         invoke  DragFinish,[wparam]
  43.         ...
Если требуется получить только один файл, то запрашивать общее количество файлов не обязательно, достаточно вызвать DragQueryFile с нулевым индексом файла. Если в интерфейсе предусмотрено несколько полей для приема файлов, то может возникнуть необходимость определять, в какое именно поле выполнятся сброс файла. Делать это можно, например, через субклассирование, но есть способ проще. При помощи функции DragQueryPoint можно определять координаты точки внутри окна, на которых был выполнен бросок файла. Сравнив их с координатами полей ввода, легко определить, какому из них предназначался файл.

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

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

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