Blog. Just Blog

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

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

Работа с escape-последовательностями на Ассемблере

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

Работа с escape-последовательностями на Ассемблере

Escape-последовательности, также известные как экранированные последовательности или символьные объекты, представляют собой особый метод представления символов внутри строк. В зависимости от синтаксиса языка, ими могут кодироваться не только ASCII-символы, но и вся последовательность юникода UTF-16 и даже UTF-32. В процессе компиляции или при отображении на экране каждая escape-последовательность заменяется на соответствующий ей код символа. Кроме этого, такую запись символов очень часто используют в различных обфускаторах для скриптов PHP и JavaScript с целью затруднения визуального анализа текстовых строк или кодирования исходных текстов. Escape-последовательность обычно распознается по начальному символу обратного слеша и фиксированному количеству символов, следующих за ним.

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

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

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

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

Моя реализация функций PHP urldecode и urlencode, а также двух их разновидностей rawurldecode и rawurlencode на Ассемблере. Алгоритм их работы описан в документации. Единственное отличие от оригинальной функции rawurlencode в том, что кодируется вся строка целиком, а не только буквенно-цифровые символы. На мой взгляд, это более логичное поведение функции с приставкой "raw". В остальном никаких отличий нет.

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

Как преобразовать кириллическую строку из UTF-8 в cp1251

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

Как преобразовать кириллическую строку из UTF-8 в cp1251

При разработке одной программы мне понадобилось преобразовать строки на русском языке из формата UTF-8 в формат cp1251. Внезапно выяснилось, что никакие средства WinAPI не позволяются выполнить эту операцию "одной строкой". Пришлось рассматривать даже варианты с табличным преобразованием, но потом нашлось более простое решение задачи. Алгоритм преобразования получился необычный, но зато гарантированно рабочий. Может быть это поможет сохранить время и нервы кому-нибудь еще.

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

Полезные функции для работы с датами на Ассемблере

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

Полезные функции для работы с датами на Ассемблере

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

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

Преобразование вещественного числа в строку на Ассемблере

14.03.2014 | Категория: Образ мышления: Assembler | Автор: ManHunter
Ранее я выкладывал статью о том, как на Ассемблере перевести строку в вещественное число, теперь настало время произвести обратную операцию, то есть перевести вещественное число в строку. В отличие от целых чисел, где достаточно нескольких строк кода, с преобразованием вещественных чисел пришлось повозиться. В результате появилась следующая функция. За основу взята аналогичная функция из пакета MASM, но со значительными доработками.
  1. ;------------------------------------------------------------
  2. ; Функция перевода вещественного числа в строку
  3. ;------------------------------------------------------------
  4. ; Портирование с MASM, доработка и оптимизация - ManHunter
  5. ; Параметры:
  6. ;   lpFloat - указатель на вещественное число TBYTE
  7. ;   lpResult - указатель на строку-приемник результата
  8. ;------------------------------------------------------------
  9. proc    FloatToString lpFloat:DWORD, lpResult:DWORD
  10.         ; Локальные переменные
  11.         local   digits_count:DWORD
  12.         local   tmp:DWORD
  13.         local   old_cw:WORD
  14.         local   new_cw:WORD
  15.         local   saved_float:TBYTE
  16.         local   tmp1 rb 12h
  17.         local   tmp2 rb 12h
  18.  
  19.         ; Сохранить все регистры
  20.         pusha
  21.  
  22.         ; Указатель на строку-приемник
  23.         mov     edi,[lpResult]
  24.  
  25.         ; Это ноль?
  26.         mov     esi,[lpFloat]
  27.         cmp     dword [esi],0
  28.         jne     loc_not_zero
  29.         cmp     dword [esi+4],0
  30.         jne     loc_not_zero
  31.         cmp     word [esi+8],0x8000
  32.         je      loc_minus_zero
  33.         cmp     word [esi+8],0
  34.         jne     loc_not_zero
  35.         ; Записать в строку ноль
  36.         mov     al,'0'
  37.         stosb
  38.         jmp     loc_ret
  39. loc_minus_zero:
  40.         ; Записать в строку минус ноль
  41.         mov     ax,'-0'
  42.         stosw
  43.         jmp     loc_ret
  44. loc_not_zero:
  45.         ; Denormalized?
  46.         mov     ax,word [esi+8]
  47.         and     ax,7F80h
  48.         or      ax,ax
  49.         jnz     loc_not_denorm
  50.         cmp     dword [esi],0
  51.         jne     loc_denorm
  52.         cmp     dword [esi+4],0
  53.         je      loc_not_denorm
  54. loc_denorm:
  55.         mov     esi,szDen
  56.         movsd
  57.         movsd
  58.         movsd
  59.         jmp     loc_ret
  60. loc_not_denorm:
  61.         ; Infinity или NaN?
  62.         mov     ax,word [esi+8]
  63.         and     ax,7F80h
  64.         cmp     ax,7F80h
  65.         jne     loc_not_inf_nan
  66.  
  67.         ; Это Infinity?
  68.         cmp     dword [esi],0
  69.         jne     loc_nan
  70.         cmp     dword [esi+4],80000000h
  71.         jne     loc_nan
  72. loc_infinity:
  73.         mov     esi,szInf
  74.         movsd
  75.         movsb
  76. loc_plus_minus:
  77.         movsd
  78.         mov     esi,[lpFloat]
  79.         test    byte [esi+9],80h
  80.         jz      loc_ret
  81.         mov     esi,[lpResult]
  82.         mov     byte[esi],'-'
  83.         jmp     loc_ret
  84. loc_nan:
  85.         mov     esi,szNan
  86.         jmp     loc_plus_minus
  87.  
  88. loc_not_inf_nan:
  89.         ; Скопировать число в локальную переменную
  90.         push    edi
  91.         mov     esi,[lpFloat]
  92.         lea     edi,[saved_float]
  93.         movsd
  94.         movsd
  95.         movsw
  96.         pop     edi
  97.         ; Число отрицательное?
  98.         cmp     dword [saved_float+6],0
  99.         jge     loc_not_signed
  100.         ; Привести число к абсолютному значению
  101.         and     byte [saved_float+9],7Fh
  102.         ; Записать в строку минус
  103.         mov     al,'-'
  104.         stosb
  105.  
  106. loc_not_signed:
  107.         ; Проверить число на наличие дробной части и
  108.         ; подсчитать количество цифр в нем
  109.         fclex
  110.         ; Сохранить управляющее слово
  111.         fstcw   [old_cw]
  112.         ; Установить управляющее слово
  113.         mov     [new_cw],0000001001111111b
  114.         fldcw   [new_cw]
  115.         lea     esi,[saved_float]
  116.         fld     tbyte [esi]
  117.         fld     st
  118.         ; Выделить мантиссу и порядок
  119.         fxtract
  120.         fstp    st
  121.         fldlg2
  122.         ; Получить количество цифр в числе
  123.         fmulp   st1,st
  124.         fistp   [digits_count]
  125.         ; Если цифр больше 16, то число отображается в
  126.         ; нормализованном виде с мантиссой и экспонентой
  127.         cmp     [digits_count],10h
  128.         jnb     loc_not_integer
  129.         ; У числа есть дробная часть?
  130.         fld     st
  131.         frndint
  132.         fcomp   st1
  133.         fstsw   ax
  134.         test    ah,01000000b
  135.         ; Да, отображать число с дробной частью
  136.         jz      loc_not_integer
  137.  
  138.         ; Целое число без дробной части и экспоненты
  139.         lea     eax,[tmp1]
  140.         fbstp   [eax]
  141.  
  142.         ; Перевести BCD-число в строку
  143.         push    edi
  144.         lea     esi,[tmp1+8]
  145.         lea     edi,[tmp2]
  146.         mov     ecx, 9
  147. @@:
  148.         std
  149.         xor     eax,eax
  150.         lodsb
  151.         cld
  152.         rol     ax,12
  153.         rol     ah,4
  154.         add     ax,'00'
  155.         stosw
  156.         loop    @b
  157.         pop     edi
  158.  
  159.         ; Пропустить лидирующий ноль
  160.         mov     eax,11h
  161.         mov     ecx,[digits_count]
  162.         sub     eax,ecx
  163.         inc     ecx
  164.         lea     esi,[tmp2+eax]
  165.         cmp     byte [esi],'0'
  166.         jne     @f
  167.         inc     esi
  168.         dec     ecx
  169. @@:
  170.         ; Перенести полученное число из временного буфера
  171.         rep     movsb
  172.         jmp     loc_clear_stack
  173.  
  174. loc_not_integer:
  175.         mov     eax,10h
  176.         sub     eax,[digits_count]
  177.  
  178.         ; Преобразовать число в целое до 16 разрядов
  179.         mov     ecx,eax
  180.         cmp     eax,0
  181.         jge     @f
  182.         neg     eax
  183. @@:
  184.         ; Для чисел больше 0 корректировка округления в сторону 0
  185.         mov     [new_cw],0000101001111111b
  186.         cmp     ecx,0
  187.         jge     @f
  188.         mov     [new_cw],0000011001111111b
  189. @@:
  190.         ; Установить управляющее слово
  191.         fldcw   [new_cw]
  192.  
  193.         ; Возвести 10 в степень количества цифр
  194.         mov     [tmp],eax
  195.         fild    [tmp]
  196.         fld     [float2]
  197.         fyl2x
  198.         fld1
  199.         fld     st1
  200.         fprem
  201.         f2xm1
  202.         faddp
  203.         fscale
  204.  
  205.         ; Почистить стек
  206.         fxch    st1
  207.         fstp    st
  208.  
  209.         ; Если число меньше 0, то умножить, иначе разделить
  210.         cmp     ecx,0
  211.         jge     @f
  212.         fdivp   st1,st
  213.         jmp     loc_rounded
  214. @@:
  215.         fmulp   st1,st
  216.  
  217. loc_rounded:
  218.         ; Полученное значение меньше 1.0e16 ?
  219.         fcom    [float1]
  220.         fstsw   ax
  221.         test    ah,1
  222.         jz      @f
  223.         fmul    [float2]
  224.         dec     [digits_count]
  225. @@:
  226.         ; Целое число без дробной части и экспоненты
  227.         lea     eax,[tmp1]
  228.         fbstp   [eax]
  229.  
  230.         ; Перевести BCD-число в строку
  231.         push    edi
  232.         lea     esi,[tmp1+8]
  233.         lea     edi,[tmp2]
  234.         mov     ecx, 9
  235. @@:
  236.         std
  237.         xor     eax,eax
  238.         lodsb
  239.         cld
  240.         rol     ax,12
  241.         rol     ah,4
  242.         add     ax,'00'
  243.         stosw
  244.         loop    @b
  245.         pop     edi
  246.  
  247.         ; Числу требуется мантисса и экспонента?
  248.         lea     esi,[tmp2+1]
  249.         mov     ecx,[digits_count]
  250.         cmp     ecx,-0Fh
  251.         jl      loc_mantiss_and_exponent
  252.         cmp     ecx,10h
  253.         jg      loc_mantiss_and_exponent
  254.  
  255.         ; Заполнить дробную часть числа
  256.         inc     ecx
  257.         cmp     ecx,0
  258.         jg      @f
  259.         mov     ax,'0.'
  260.         stosw
  261.         neg     ecx
  262.         mov     al,'0'
  263.         rep     stosb
  264.         mov     ecx,10h
  265.         jmp     loc_fraction_filled
  266. @@:
  267.         rep     movsb
  268.         mov     al,'.'
  269.         stosb
  270.         mov     ecx,10h
  271.         sub     ecx,[digits_count]
  272.  
  273. loc_fraction_filled:
  274.         rep     movsb
  275.         jmp     @f
  276.  
  277. loc_clear_fraction:
  278.         ; Удалить завершающие нули дробной части
  279.         dec     edi
  280. @@:
  281.         cmp     byte [edi-1],'0'
  282.         jz      loc_clear_fraction
  283.         cmp     byte [edi-1],'.'
  284.         jnz     @f
  285.         dec     edi
  286. @@:
  287.         jmp     loc_clear_stack
  288.  
  289. loc_mantiss_and_exponent:
  290.         ; Дробная часть мантиссы
  291.         movsb
  292.         mov     al,'.'
  293.         stosb
  294.         movsd
  295.         movsd
  296.         movsw
  297.         ; Удалить завершающие нули дробной части
  298. @@:
  299.         cmp     byte [edi-1],'0'
  300.         jne     @f
  301.         cmp     byte [edi-2],'.'
  302.         je      @f
  303.         dec     edi
  304.         jmp     @b
  305. @@:
  306.         ; Символ и знак экспоненты
  307.         mov     al,'e'
  308.         stosb
  309.         mov     al,'+'
  310.         mov     ebx,[digits_count]
  311.         cmp     ebx, 0
  312.         jge     @f
  313.         mov     al,'-'
  314.         neg     ebx
  315. @@:
  316.         stosb
  317.  
  318.         ; Значение экспоненты
  319.         mov     eax,ebx
  320.         mov     ecx,10
  321.         mov     ebx,4
  322. @@:
  323.         dec     ebx
  324.         xor     edx,edx
  325.         div     ecx
  326.         add     dl,'0'
  327.         mov     [tmp1+ebx],dl
  328.         or      ebx,ebx
  329.         jnz     @b
  330.  
  331.         ; Пропустить лидирующие нули экспоненты
  332.         mov     ecx,4
  333.         lea     esi,[tmp1]
  334. @@:
  335.         lodsb
  336.         cmp     al,'0'
  337.         jne     @f
  338.         dec     ecx
  339.         jmp     @b
  340. @@:
  341.         dec     esi
  342.         rep     movsb
  343.  
  344. loc_clear_stack:
  345.         ; Восстановить управляющее слово
  346.         fldcw   [old_cw]
  347. loc_ret:
  348.         ; Окончание строки
  349.         mov     al,0
  350.         stosb
  351.  
  352.         ; Восстановить все регистры
  353.         popa
  354.         ret
  355.  
  356. float1  dq      1.0e16
  357. float2  dq      10.0
  358.  
  359. szInf   db      '+Infinity'
  360. szNan   db      '+NaN'
  361. szDen   db      'Denormalized'
  362.  
  363. endp
Параметры вызова: lpFloat - указатель на вещественное число TBYTE (10 байт), lpResult - указатель на строку-приемник результата. Функция самодостаточная, не требует никаких дополнительных переменных в секции данных и вспомогательных функций, исходное число не меняется. В отличие от MASM'овской функции, поддерживаются вещественные числа в диапазоне -1e4932..+1e4932, увеличено количество отображаемых цифр после запятой, улучшена точность округления мантиссы для очень больших и очень маленьких чисел, улучшено форматирование значения экспоненты и выполнены другие действия по оптимизации алгоритма.

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

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