Все, кто что знает по поводу сабжа, предлагаю выкладывать здесь, авось еще кому-нить пригодится. (все компиляторы, платформа х86). Собственно начну, а кому интересно подключайтесь: 0. Очистка регистра: Код (Text): xor reg,reg ; страшно подумать, но многие по сей день очищают регистры командой mov :) sub reg,reg ; экономия байтов 1. Очистка стека от одного элемента: Код (Text): pop reg ; reg - регистр с неактуальными данными, как правило - сх. Экономия байтов. 2. Очистка стека после нескольких вызовов cdecl функций: Код (Text): push somevar1 call f1 push somevar2 call f2 push somevar3 call f3 add esp,3*4 ; в данном случае вместо трех очисток - только одна. Экономия команд. 3. Сложение 3-х значений, путем вычисления эффективного адреса: Код (Text): lea reg1,[reg2+reg3+const]; экономия на командах add, но флаги не устанавливаются. 4. Умножение(деление) на степень кратную 2(2,4,8....). Выполняется сдвигом. Код (Text): shl (shr) reg,n ; где n=log2(множитель). 5. Вместо умножения на константу, можно вычислить эффективный(ые) адрес(а): Код (Text): lea reg,[reg*n+reg] ; умножение reg на 2,3,4,5,8,9 ...
ALLeX Спасибо! .. Так вроде знаешь туеву хучу идиом, а вспомнить даже десяток - проблематично. Вот, что дополнительно из той ссылки вспомнил или узнал: 6. Модуль числа: А. Версия нерабочая, рабочие в постах №8-10 Код (Text): @locallabel: neg ax js short @locallabel ; типа самый примитивный случай Два примера без ветвлений: Б.Visual C (Thx Quantum) Код (Text): cwd xor ax,dx sub ax,dx В. Код (Text): mov dx,ax sar dx,15 xor ax,dx sub ax,dx 7. Деление знаковых чисел на степень 2 А. Код (Text): ; ; signed division by 2 ; ; input: ; eax = dividend ; ; output: ; eax = quotient ; ; destroys: ; eflags ; cmp eax,080000000h ; CY = 1, if dividend >= 0 sbb eax,-1 ; increment dividend if it is < 0 sar eax,1 ; now do right shift Б. Код (Text): ; ; signed division by d = 2^k ; ; input: ; eax = dividend ; ; output: ; eax = quotient ; ; destroys: ; edx ; eflags ; cdq ; EDX = 0xFFFFFFFF if dividend < 0 and edx,(d-1) ; mask correction (use divisor-1) add eax,edx ; apply correction if necessary sar eax,k ; now do right shift by log2(divisor) 8. Деление знаковых чисел на степень -2 А. Код (Text): ; ; signed division by -2 ; ; input: ; eax = dividend ; ; output: ; eax = quotient ; ; destroys: ; eflags ; cmp eax,080000000h ; CY = 1, if dividend >= 0 sbb eax,-1 ; increment dividend if it is < 0 sar eax,1 ; now do right shift neg eax ; use (x / -2) == -(x / 2) Б. Код (Text): ; ; signed division by d = -(2^k) ; ; input: ; eax = dividend ; ; output: ; eax = quotient ; ; destroys: ; edx ; eflags ; cdq ; EDX = mask = 0xFFFFFFFF if divdnd < 0 and edx,(-d-1) ; mask correction (-divisor - 1) add eax,edx ; apply correction if necessary sar eax,k ; do right shift by log2(-divisor) neg eax ; use (x / -(2^n)) == (- (x / 2^n)) 9. Остатки от деления знаковых чисел: А. Код (Text): ; ; remainder of signed division by 2 or -2 ; ; input: ; eax = dividend ; ; output: ; eax = remainder ; ; destroys: ; edx ; eflags ; cdq ; flag = EDX = 0xFFFFFFFF if divdnd < 0 and eax,1 ; compute remainder xor eax,edx ; negate remainder if sub eax,edx ; dividend was < 0 Б. Код (Text): ; ; remainder of signed division by d = 2^k or -(2^k) ; ; input: ; eax = dividend ; ; output: ; eax = remainder ; ; destroys: ; edx ; eflags ; cdq ; EDX = mask = 0xFFFFFFFF if divdnd < 0 and edx,(abs(d)-1) ; mask correction (abs(divisor)-1) add eax,edx ; apply pre-correction and eax,(abs(d)-1) ; mask out remainder (abs(divisor)-1) sub eax,edx ; apply post-correction if necessary 10. Ноп`ы-заполнители: Код (Text): 1-bytes NOP ; true NOP 2-bytes mov reg,reg ; true NOP 2-bytes xchg ax,ax ; true NOP 3-bytes lea reg,[reg+0] ; true NOP, use 8-bit 4-bytes shl eax,0 ; true NOP 5-bytes shrd eax,eax,0 ; true NOP 6-bytes lea eax,[eax+0] ; true NOP 11. Еще компилеры любят заполнять нулями 0х00 и инт3 0хСС. 12. Обмен двух переменных А. Код (Text): push ax push bx pop ax pop bx ; прямо как в школе учили :) Б. Код (Text): xor ax,bx xor bx,ax xor ax,bx ; А этот приемчик кажется в Уоррене был :) ЗЫ: Пожалуй, лучшей ссылкой является: ВВВ.ИсходникиКомпилера.ОРГ ЗЗЫ: Придется наверно лесть в ДСС и Бумеранг чтоб систематизировать все это , а то народ не активный какой-то
masquer Действительно для -maxint результат не меняется а sign постоянно взведен. Все претензии к авторам вышеуказанной ссылки Вот глупая, но исправленная версия 6 А. Код (Text): @locallabel: neg ax jns short @locallabel ; neg ax Всем по прежнему спасибо за участие.
Проверил, с jl работает. Умная и исправленная версия : 6 А. Код (Text): @locallabel: neg ax jl short @locallabel ; надеюсь здесь ошибок нет ...