Предлагаю здесь собрать идиомы для себя и будущих поколений ...

Тема в разделе "WASM.RESEARCH", создана пользователем _Serega_, 19 окт 2006.

  1. _Serega_

    _Serega_ New Member

    Публикаций:
    0
    Регистрация:
    18 июн 2006
    Сообщения:
    288
    Все, кто что знает по поводу сабжа, предлагаю выкладывать здесь, авось еще кому-нить пригодится. (все компиляторы, платформа х86).

    Собственно начну, а кому интересно подключайтесь:

    0. Очистка регистра:
    Код (Text):
    1. xor reg,reg ; страшно подумать, но многие по сей день очищают регистры командой mov :)
    2. sub reg,reg ; экономия байтов
    1. Очистка стека от одного элемента:
    Код (Text):
    1. pop reg ; reg - регистр с неактуальными данными, как правило - сх. Экономия байтов.
    2. Очистка стека после нескольких вызовов cdecl функций:
    Код (Text):
    1. push somevar1
    2. call f1
    3. push somevar2
    4. call f2
    5. push somevar3
    6. call f3
    7. add esp,3*4 ; в данном случае вместо трех очисток - только одна. Экономия команд.
    3. Сложение 3-х значений, путем вычисления эффективного адреса:
    Код (Text):
    1. lea reg1,[reg2+reg3+const]; экономия на командах add, но флаги не устанавливаются.
    4. Умножение(деление) на степень кратную 2(2,4,8....). Выполняется сдвигом.
    Код (Text):
    1. shl (shr) reg,n ; где n=log2(множитель).
    5. Вместо умножения на константу, можно вычислить эффективный(ые) адрес(а):
    Код (Text):
    1. lea reg,[reg*n+reg] ; умножение reg на 2,3,4,5,8,9
    ...
     
  2. ALLeX

    ALLeX Member

    Публикаций:
    0
    Регистрация:
    21 окт 2004
    Сообщения:
    141
    Адрес:
    Ukraine
  3. _Serega_

    _Serega_ New Member

    Публикаций:
    0
    Регистрация:
    18 июн 2006
    Сообщения:
    288
    ALLeX Спасибо! .. Так вроде знаешь туеву хучу идиом, а вспомнить даже десяток - проблематично. Вот, что дополнительно из той ссылки вспомнил или узнал:

    6. Модуль числа:
    А. Версия нерабочая, рабочие в постах №8-10
    Код (Text):
    1. @locallabel:
    2.         neg     ax
    3.         js      short @locallabel ; типа самый примитивный случай
    Два примера без ветвлений:
    Б.Visual C (Thx Quantum)
    Код (Text):
    1.         cwd
    2.         xor     ax,dx
    3.         sub     ax,dx
    В.
    Код (Text):
    1.         mov     dx,ax
    2.         sar     dx,15
    3.         xor     ax,dx
    4.         sub     ax,dx
    7. Деление знаковых чисел на степень 2
    А.
    Код (Text):
    1. ;
    2. ; signed division by 2
    3. ;
    4. ; input:
    5. ;   eax = dividend
    6. ;
    7. ; output:
    8. ;   eax = quotient
    9. ;
    10. ; destroys:
    11. ;   eflags
    12. ;
    13.  
    14.         cmp     eax,080000000h  ; CY = 1, if dividend >= 0
    15.         sbb     eax,-1          ; increment dividend if it is < 0
    16.         sar     eax,1           ; now do right shift
    Б.
    Код (Text):
    1. ;
    2. ; signed division by d = 2^k
    3. ;
    4. ; input:
    5. ;   eax = dividend
    6. ;
    7. ; output:
    8. ;   eax = quotient
    9. ;
    10. ; destroys:
    11. ;   edx
    12. ;   eflags
    13. ;
    14.  
    15.         cdq                     ; EDX = 0xFFFFFFFF if dividend < 0
    16.         and     edx,(d-1)       ; mask correction (use divisor-1)
    17.         add     eax,edx         ; apply correction if necessary
    18.         sar     eax,k           ; now do right shift by log2(divisor)
    8. Деление знаковых чисел на степень -2
    А.
    Код (Text):
    1. ;
    2. ; signed division by -2
    3. ;
    4. ; input:
    5. ;   eax = dividend
    6. ;
    7. ; output:
    8. ;   eax = quotient
    9. ;
    10. ; destroys:
    11. ;   eflags
    12. ;
    13.  
    14.         cmp     eax,080000000h  ; CY = 1, if dividend >= 0
    15.         sbb     eax,-1          ; increment dividend if it is < 0
    16.         sar     eax,1           ; now do right shift
    17.         neg     eax             ; use (x / -2) ==  -(x / 2)
    Б.
    Код (Text):
    1. ;
    2. ; signed division by d = -(2^k)
    3. ;
    4. ; input:
    5. ;   eax = dividend
    6. ;
    7. ; output:
    8. ;   eax = quotient
    9. ;
    10. ; destroys:
    11. ;   edx
    12. ;   eflags
    13. ;
    14.  
    15.         cdq                     ; EDX = mask = 0xFFFFFFFF if divdnd < 0
    16.         and     edx,(-d-1)      ; mask correction (-divisor - 1)
    17.         add     eax,edx         ; apply correction if necessary
    18.         sar     eax,k           ; do right shift by log2(-divisor)
    19.         neg     eax             ; use (x / -(2^n)) == (- (x / 2^n))
    9. Остатки от деления знаковых чисел:
    А.
    Код (Text):
    1. ;
    2. ; remainder of signed division by 2 or -2
    3. ;
    4. ; input:
    5. ;   eax = dividend
    6. ;
    7. ; output:
    8. ;   eax = remainder
    9. ;
    10. ; destroys:
    11. ;   edx
    12. ;   eflags
    13. ;
    14.  
    15.         cdq                     ; flag = EDX = 0xFFFFFFFF if divdnd < 0
    16.         and     eax,1           ; compute remainder
    17.         xor     eax,edx         ; negate remainder if
    18.         sub     eax,edx         ;  dividend was < 0
    Б.
    Код (Text):
    1. ;
    2. ; remainder of signed division by d = 2^k or -(2^k)
    3. ;
    4. ; input:
    5. ;   eax = dividend
    6. ;
    7. ; output:
    8. ;   eax = remainder
    9. ;
    10. ; destroys:
    11. ;   edx
    12. ;   eflags
    13. ;
    14.  
    15.         cdq                     ; EDX = mask = 0xFFFFFFFF if divdnd < 0
    16.         and     edx,(abs(d)-1)  ; mask correction (abs(divisor)-1)
    17.         add     eax,edx         ; apply pre-correction
    18.         and     eax,(abs(d)-1)  ; mask out remainder (abs(divisor)-1)
    19.         sub     eax,edx         ; apply post-correction if necessary
    10. Ноп`ы-заполнители:
    Код (Text):
    1. 1-bytes         NOP                         ; true NOP
    2. 2-bytes         mov     reg,reg         ; true NOP
    3. 2-bytes         xchg    ax,ax           ; true NOP
    4. 3-bytes         lea     reg,[reg+0]     ; true NOP, use 8-bit
    5. 4-bytes         shl     eax,0           ; true NOP
    6. 5-bytes         shrd    eax,eax,0       ; true NOP
    7. 6-bytes         lea     eax,[eax+0]     ; true NOP
    11. Еще компилеры любят заполнять нулями 0х00 и инт3 0хСС.

    12. Обмен двух переменных
    А.
    Код (Text):
    1.         push    ax
    2.         push    bx
    3.         pop     ax
    4.         pop     bx ; прямо как в школе учили :)
    Б.
    Код (Text):
    1.         xor     ax,bx
    2.         xor     bx,ax
    3.         xor     ax,bx ; А этот приемчик кажется в Уоррене был :)
    ЗЫ: Пожалуй, лучшей ссылкой является: ВВВ.ИсходникиКомпилера.ОРГ :)
    ЗЗЫ: Придется наверно лесть в ДСС и Бумеранг чтоб систематизировать все это :), а то народ не активный какой-то :dntknw:
     
  4. masquer

    masquer wasm.ru

    Публикаций:
    0
    Регистрация:
    13 сен 2002
    Сообщения:
    890
    Адрес:
    Николаев
    код неверный (для варианта А)
     
  5. Quantum

    Quantum Паладин дзена

    Публикаций:
    0
    Регистрация:
    6 янв 2003
    Сообщения:
    3.143
    Адрес:
    Ukraine
    masquer
    Почему?

    _Serega_
    6.B
    Вижуал C именно так abs оптимизирует.
     
  6. Mescalito

    Mescalito New Member

    Публикаций:
    0
    Регистрация:
    31 мар 2005
    Сообщения:
    78
    Адрес:
    Харьков
    Quantum
    ...
    (загнался)
     
  7. masquer

    masquer wasm.ru

    Публикаций:
    0
    Регистрация:
    13 сен 2002
    Сообщения:
    890
    Адрес:
    Николаев
    Quantum
    ну, например, потому, что его легко загнать в вечный цикл :)
     
  8. _Serega_

    _Serega_ New Member

    Публикаций:
    0
    Регистрация:
    18 июн 2006
    Сообщения:
    288
    masquer
    Действительно для -maxint результат не меняется а sign постоянно взведен. Все претензии к авторам вышеуказанной ссылки :)
    Вот глупая, но исправленная версия :)
    6 А.
    Код (Text):
    1.         @locallabel:
    2.         neg     ax
    3.         jns      short @locallabel ;
    4.         neg     ax
    Всем по прежнему спасибо за участие.
     
  9. masquer

    masquer wasm.ru

    Публикаций:
    0
    Регистрация:
    13 сен 2002
    Сообщения:
    890
    Адрес:
    Николаев
    просто jl вместо js написать и все будет нормально
     
  10. _Serega_

    _Serega_ New Member

    Публикаций:
    0
    Регистрация:
    18 июн 2006
    Сообщения:
    288
    Проверил, с jl работает. Умная и исправленная версия :) :
    6 А.
    Код (Text):
    1.         @locallabel:
    2.         neg     ax
    3.         jl      short @locallabel ; надеюсь здесь ошибок нет ...