1. Если вы только начинаете программировать на ассемблере и не знаете с чего начать, тогда попробуйте среду разработки ASM Visual IDE
    (c) на правах рекламы
    Скрыть объявление

Asm coding tricks

Тема в разделе "WASM.A&O", создана пользователем S_T_A_S_, 1 янв 2005.

  1. S_T_A_S_

    S_T_A_S_ New Member

    Публикаций:
    0
    Регистрация:
    27 окт 2003
    Сообщения:
    1.755
    Предлагаю в этом топе собирать всевозможные "маленикие хитрости", которые бывают полезны для оптимизации кода по размеру и/или скорости.



    Для кого-то, возможно, эти вещи очевидны, а для кого-то нет, но обмен опытом imho никому не помешает.

    _______________________________________________________



    Вот элементарный пример:



    Операция AND позволяет обнулить биты в приёмнике, по источнику "маске" - биты приёмника, соответствующие нулевым битам маски обнуляются.

    Иногда, нужно обнулить биты приёмника, соответствующие единичным битам маски.

    очевидный вриант - инвертировать маску:
    Код (Text):
    1.  
    2. ; eax - приёмник
    3. ; edx - "инвертированная" маска
    4.  
    5.         not  edx
    6.         and  eax, edx


    А если маска далее нужна в неинвертированном виде?

    можно делать по-другому:
    Код (Text):
    1.  
    2.         or   eax, edx
    3.         xor  eax, edx


    _______________________________________________________



    Часто необходимо сравнить регистр с некоторым числом, и, если значение в регистре меньше, поместить в него (или в другой регистр) одно занчение (value<sub>1</sub>), иначе - другое (value<sub>2</sub>).



    Без ветвлений это можно делать так:
    Код (Text):
    1.  
    2.         cmp  eax, some_number
    3.         sbb  eax, eax          ;  0 или FFFFFFFF
    4.         and  eax, value<sub>1</sub> - value<sub>2</sub>
    5.         add  eax, value<sub>2</sub>


    Частный вариант - value<sub>2</sub> = 0, в этом случае последняя строка не нужна.



    _______________________________________________________



    Для циклов обычно используется отдельная переменная (или регистр).

    Однако, если в цикле ипользуется операция сдвига, то в качестве "счётчика" можно использовать сам сдвигаемый регистр.

    Наглядный пример - перевод числа в двоичное представление:
    Код (Text):
    1.  
    2. ; ecx - число
    3. ; edi - адрес буфера, куда поместим ASCII строку
    4.  
    5.         stc                      ; "33й бит" - маркер
    6. l00p:   mov     al, 30
    7.         rcl     ecx, 1           ; циклически сдвигаем регистр с маркером
    8.         adc     al, "0"
    9.         stos    byte[edi]
    10.         inc     ecx              ; маркер выйдет за пределы регистра после 32х итераций и ecx будет равен 0
    11.         loop    l00p             ; inc ecx + loop "короткий" аналог test ecx, ecx + jnz
    12.  
     
  2. captain cobalt

    captain cobalt New Member

    Публикаций:
    0
    Регистрация:
    21 дек 2003
    Сообщения:
    222
    Адрес:
    /ru/perm
    "Алгоритмические трюки" Уоррена переписать сюда? :)
     
  3. S_T_A_S_

    S_T_A_S_ New Member

    Публикаций:
    0
    Регистрация:
    27 окт 2003
    Сообщения:
    1.755
    У меня (почему-то до сих пор, наверное из-за лени ?) нет этой книги =)

    К тому же, мне кажется, что мой третий пример ^ в ней не рассматривается ;)
     
  4. Black_mirror

    Black_mirror Active Member

    Публикаций:
    0
    Регистрация:
    14 окт 2002
    Сообщения:
    1.036
    Если нужно увеличить/уменьшить число, занимающее биты с H по L:
    Код (Text):
    1. N H L  0
    2. XXNNNXXX
    3.  
    4. rol reg,N-H
    5. add/sub reg,(v shl N-H)
    6. ror reg,N-H
     
  5. yureckor

    yureckor New Member

    Публикаций:
    0
    Регистрация:
    25 фев 2004
    Сообщения:
    494
    Адрес:
    Russia
    обменять регистры
    Код (Text):
    1.  
    2. obmen_reg macro a,b
    3. xor a,b
    4. xor b,a
    5. xor a,b
    6. endm
    7.  
     
  6. AsmGuru62

    AsmGuru62 Member

    Публикаций:
    0
    Регистрация:
    12 сен 2002
    Сообщения:
    689
    Адрес:
    Toronto
  7. EvilsInterrupt

    EvilsInterrupt Постигающий азы дзена

    Публикаций:
    0
    Регистрация:
    28 окт 2003
    Сообщения:
    2.428
    Адрес:
    Russia
    >обменять регистры

    Красиво однако
     
  8. flankerx

    flankerx New Member

    Публикаций:
    0
    Регистрация:
    2 июл 2004
    Сообщения:
    423
    Адрес:
    Moscow, Russia
    yureckor

    этот способ обмена не универсален: в случае, если a и b -- одно и то же, он будет работать неправильно :)
     
  9. S_T_A_S_

    S_T_A_S_ New Member

    Публикаций:
    0
    Регистрация:
    27 окт 2003
    Сообщения:
    1.755
    При вызове WinAPI функций, очень часто нужно передавать адрес переменной размером dword, куда будет записано возвращаемое значение. Обычно для этих целей создаётся отдельная локальная переменная (HLL way) или, того хуже, глобальная.



    Существует более компактный способ:
    Код (Text):
    1.  
    2.         push    ecx       ; создаём локальную переменную
    3.         mov     ecx, esp  ; её адрес
    4.         invoke  ReadFile, hFile, lpBuffer, nNumberOfBytesToRead, ecx, lpOverlapped
    5.         pop     ecx       ; считываем значение
     
  10. S_T_A_S_

    S_T_A_S_ New Member

    Публикаций:
    0
    Регистрация:
    27 окт 2003
    Сообщения:
    1.755
    При оптимизации по размеру может быть полезен такой способ загрузки параметров stdcall функции в регистры:
    Код (Text):
    1.  
    2. foo_proc:
    3.         push   esi        ; если нужно, сохраняем esi
    4.         mov    esi, esp
    5.         lods   dword[esi] ; пропускаем сохранённый esi
    6.         lods   dword[esi] ; пропускаем адрес возврата
    7.         lods   dword[esi] ; 1й аргумент
    8.         xchg   eax, ecx   ; в ecx
    9.         lods   dword[esi] ; 2й аргумент
    10.         xchg   eax, edx   ; в edx
    11.         lods   dword[esi] ; 3й аргумент в eax
    12.  
     
  11. Max

    Max Member

    Публикаций:
    0
    Регистрация:
    22 май 2003
    Сообщения:
    192
    S_T_A_S_

    есть такая замечательная книжка - "Hackers Delight".

    там дохрена "маленьких хитростей".

    в инете встречается крайне редко, проси Володю - она у него есть ;)
     
  12. tasman

    tasman New Member

    Публикаций:
    0
    Регистрация:
    25 май 2004
    Сообщения:
    44
    Адрес:
    Ukraine
    Max

    "Алгоритмические трюки" Уоррена это и есть перевод "Hackers Delight".
     
  13. Max

    Max Member

    Публикаций:
    0
    Регистрация:
    22 май 2003
    Сообщения:
    192
    tasman

    блин, внатуре, автор то - Henry S. Warren, а я и не знал :)

    но вот перевод названия мягко говоря - вольный :)
     
  14. S_T_A_S_

    S_T_A_S_ New Member

    Публикаций:
    0
    Регистрация:
    27 окт 2003
    Сообщения:
    1.755
    Народ, ну неужели в "Hackers Delight" будут описываться архитектурные особенности x86-32 и / или win ?
     
  15. Stiver

    Stiver Партизан дзена

    Публикаций:
    0
    Регистрация:
    18 дек 2004
    Сообщения:
    812
    Адрес:
    Germany
    Max





    Не знаю как в Интернете, ради интереса посмотрел на Undernete и нашел с ходу штук 10.
     
  16. volodya

    volodya wasm.ru

    Публикаций:
    0
    Регистрация:
    22 апр 2003
    Сообщения:
    1.169
    Так, хватит тут оффтоп разводить. А что у Володи есть - так нечего об этом публично заявлять ;) Знаток закромов Родины выискался, млин :)
     
  17. Asterix

    Asterix New Member

    Публикаций:
    0
    Регистрация:
    25 фев 2003
    Сообщения:
    3.576
    Код (Text):
    1. Уоррен Г.
    2. Алгоритмические трюки для программистов: Пер. с англ., Вильямс, 2003 г. - 288 с.
    3. «Hacker's Delight»
    4.  
    5. ISBN: 5-8459-0471-4




    Не так уж и сложно найти в сети :derisive:
     
  18. varnie

    varnie New Member

    Публикаций:
    0
    Регистрация:
    2 янв 2005
    Сообщения:
    1.787
    урликом на эту книжку не поделитесь?
     
  19. shoo

    shoo New Member

    Публикаций:
    0
    Регистрация:
    17 июл 2003
    Сообщения:
    1.537
    Адрес:
    Ukraine
    однажды я ломал игру, так там из начального байта вычитался байт типа 0DEh. так вот через n=(число жизней) вычитаний этот байт обнулялся, и - гейм овер. не совсем асм, и может устарело, но и не очень-то заметно по сравнению с простым dec или sub 1 ;)
     
  20. Stiver

    Stiver Партизан дзена

    Публикаций:
    0
    Регистрация:
    18 дек 2004
    Сообщения:
    812
    Адрес:
    Germany
    varnie





    URL не поделимся, потому как за Warez шею намылят ;) Если еще не нашел, давай свой адрес.