и еще чуть-чуть Код (Text): mov eax,0ABCDEF0h mov esi,0Fh xor ebp,ebp xor ecx,ecx mov ebx,eax rept 7 ror ebx,4 mov edx,ebx xor edx,eax rept 8 test edx,esi setz cl ror esi,4 or ebp,ecx endm endm dec ebp xchg eax,ebp
Booster >Не катит, в условии чётко сказано - "Без переходов". Чепуха, досрочный выход из тела (онейронавты, молчать!) за ветвления не считается.
Black_mirror Циклов нет, а JMP для досрочного выхода это даже хорошо =))) Пишу из головы, поэтому для реального применения может потребоваться отладка и доводка… Кста, стек увеличивается или уменьшается когда в него кладут? Будем считать для определенности, что уменьшается… mov ecx,eax xor eax,eax //код возврата mov ebp,esp sub esp,16 mov [ebp],02020202h mov [ebp-4],02020202h mov [ebp-8],02020202h mov [ebp-12],02020202h mov edx,ecx and edx,15 dec byte[ebp-edx] shr ecx,4 mov edx,ecx and edx,15 dec byte[ebp-edx] jz @quit shr ecx,4 mov edx,ecx and edx,15 dec byte[ebp-edx] jz @quit shr ecx,4 mov edx,ecx and edx,15 dec byte[ebp-edx] jz @quit shr ecx,4 mov edx,ecx and edx,15 dec byte[ebp-edx] jz @quit shr ecx,4 mov edx,ecx and edx,15 dec byte[ebp-edx] jz @quit shr ecx,4 mov edx,ecx and edx,15 dec byte[ebp-edx] jz @quit shr ecx,4 mov edx,ecx and edx,15 dec byte[ebp-edx] jz @quit dec eax // теперь код возврата -1 :@quit add esp,16
если взять за основу идею persicum Код (Text): mov eax,0ABCDEF0h xor ebp,ebp xor edx,edx rept 8 mov ebx,eax and ebx,0Fh add tabl[ebx],1 shr eax,4 endm mov esi,offset tabl rept 16 lodsb test al,0FEh setnz dl or ebp,edx endm dec ebp xchg eax,ebp .data tabl db 16 dup (0)
похож наврал, лучше mov [ebp-3],02020202h mov [ebp-7],02020202h mov [ebp-11],02020202h mov [ebp-15],02020202h
Да, и в начеле еще наверное нужно dec ebp Блин, честные юзары в стек только пушают и попают, это только зловреды умеют в нем ковыряться...
так короче Код (Text): mov eax,0ABCDEF0h xor ebp,ebp xor edx,edx rept 8 mov ebx,eax and ebx,0Fh add tabl[ebx],1 shr eax,4 endm mov esi,offset tabl push esi mov edi,esi rept 16 lodsb shr al,1; оставляю числа больше 1 stosb endm pop esi rept 4 lodsd test eax,eax setnz dl or ebp,edx endm dec ebp xchg eax,ebp .data tabl db 16 dup (0)
а так еще короче Код (Text): mov eax,1ABCDEF0h xor ebp,ebp xor edx,edx rept 8 mov ebx,eax and ebx,0Fh add tabl[ebx],1 shr eax,4 endm mov esi,offset tabl rept 4 lodsd and eax,0FEFEFEFEh test eax,eax setnz dl or ebp,edx endm dec ebp xchg eax,ebp .data tabl db 16 dup (0)
murder [offtop]Команду AAD обычно используют для подготовки двух неупакованных BCD-цифр (в регистре AH находится число десятков, в регистре AL – число единиц) для операции деления, которая вернет результат в неупакованном виде. Это выполняется установкой регистра AL равным AL+(10*AH) и сбросом AH в 0. После этого в регистре AX находится двоичный эквивалент исходного неупакованного числа из двух цифр. Код команды AAD равен 0D50Ah, попробуйте вставить в вашу программу команду DB 0D5h,20h и вы обнаружите, что после такого кода содержимое регистра AL станет равным AL+(32*AH). Недостаток такого умножения – результат не может быть больше 255, так как содержимое регистра AH будет обнуляться. Команду AAD можно использовать если необходимо разделить содержимое регистра AH на 10. Команда AAM осуществляет деление содержимого регистра AL на 10 и загружает частное в регистр AH, а остаток – в регистр AL. Код команды AAM равен 0D40Ah, попробуйте вставить в вашу программу команду db 0D4h,07 и вы обнаружите, что после такого кода содержимое регистра AL будет поделено на 7, в регистр AH загружено частное, а остаток – в регистре AL. Недостаток такого деления – делимое не может быть больше 255, так как содержимое регистра AH будет игнорироваться. Статья st0ne [HUGI] с сайта asm.shadrinsk.net: "Скрытая мощь BCD-инструкций"[/offtop]
Вариант с циклом, 21 байт: Код (Text): 00402000 /$ 31D2 XOR EDX,EDX 00402002 |. B1 01 MOV CL,1 00402004 |> C1C0 04 /ROL EAX,4 00402007 |. 66:0FABC2 |BTS DX,AX 0040200B |. 10C9 |ADC CL,CL 0040200D |.^73 F5 \JNB SHORT q.00402004 0040200F |. F6D9 NEG CL 00402011 |. 19C0 SBB EAX,EAX 00402013 |. F7D0 NOT EAX 00402015 Вариант без цикла, 69 байт: Код (Text): 00402000 /$ 31D2 XOR EDX,EDX 00402002 |. 0FABC2 BTS EDX,EAX 00402005 |. B1 04 MOV CL,4 00402007 |. D3C0 ROL EAX,CL 00402009 |. 0FABC2 BTS EDX,EAX 0040200C |. 19DB SBB EBX,EBX 0040200E |. D3C0 ROL EAX,CL 00402010 |. 0FABC2 BTS EDX,EAX 00402013 |. 11DB ADC EBX,EBX 00402015 |. D3C0 ROL EAX,CL 00402017 |. 0FABC2 BTS EDX,EAX 0040201A |. 11DB ADC EBX,EBX 0040201C |. D3C0 ROL EAX,CL 0040201E |. 0FABC2 BTS EDX,EAX 00402021 |. 11DB ADC EBX,EBX 00402023 |. D3C0 ROL EAX,CL 00402025 |. 0FABC2 BTS EDX,EAX 00402028 |. 11DB ADC EBX,EBX 0040202A |. D3C0 ROL EAX,CL 0040202C |. 0FABC2 BTS EDX,EAX 0040202F |. 11DB ADC EBX,EBX 00402031 |. D3C0 ROL EAX,CL 00402033 |. 0FABC2 BTS EDX,EAX 00402036 |. 11DB ADC EBX,EBX 00402038 |. 0FA4D3 10 SHLD EBX,EDX,10 0040203C |. 66:21D3 AND BX,DX 0040203F |. F7DB NEG EBX 00402041 |. 19C0 SBB EAX,EAX 00402043 |. F7D0 NOT EAX 00402045
69 байт с циклом. Ничего особенного, но важен процесс, а не результат. Код (Text): movd mm0,eax movq mm1,mm0 psllq mm1,28 por mm0,mm1 mov ax,$0F0F pinsrw mm1,eax,0 pshufw mm1,mm1,0 pand mm0,mm1 movq mm2,mm1 psrlw mm1,3 pand mm1,mm2 mov ecx,16 @@:movq mm3,mm2 pcmpeqb mm3,mm0 pmovmskb eax,mm3 psubb mm2,mm1 popcnt eax,eax sub al,1 jnle @f loop @b @@: sbb eax,eax
Насколько я понял вариантавтора - 29 комманд, байты не считал. Я слегка не дотянул - вариант 30 комманд, без цикла, 83 байта: Код (Text): mov esi, eax mov ebx, eax mov ecx, eax mov edx, eax ror esi, 4 xor eax, esi ror esi, 4 xor ebx, esi ror esi, 4 xor ecx, esi ror esi, 4 xor edx, esi lea esi, [eax-11111111h] not eax and eax, esi lea esi, [ebx-11111111h] not ebx and ebx, esi or eax, ebx lea esi, [ecx-11111111h] not ecx and ecx, esi or eax, ecx lea esi, [edx-11111111h] not edx and edx, esi or eax, edx and eax, 88888888h neg eax sbb eax, eax
с циклом 46 байт + 16 байт данные Код (Text): xor ebp,ebp xor edx,edx mov esi,offset tabl mov ecx,8 a1: mov ebx,eax and ebx,0Fh add byte ptr [esi+ebx],1 shr eax,4 loop a1 mov ebx,0FEFEFEFEh mov cl,4 a2: lodsd and eax,ebx setnz dl or ebp,edx loop a2 xchg eax,ebp dec eax tabl db 16 dup (0)
Вариант автора - 29 комманд, я немного не дотянул - 30. Без цикла, 83 байта. Код (Text): mov esi, eax mov ebx, eax mov ecx, eax mov edx, eax ror esi, 4 xor eax, esi ror esi, 4 xor ebx, esi ror esi, 4 xor ecx, esi ror esi, 4 xor edx, esi lea esi, [eax-11111111h] not eax and eax, esi lea esi, [ebx-11111111h] not ebx and ebx, esi or eax, ebx lea esi, [ecx-11111111h] not ecx and ecx, esi or eax, ecx lea esi, [edx-11111111h] not edx and edx, esi or eax, edx and eax, 88888888h neg eax sbb eax, eax
Извиняюсь, что 2 раза - то ли у меня глюк, то ли на сайте. Пост вроде ушел, но в теме не появился. Только через минуту
Black_mirror Где вариант без цикла, там нет опечаток? Либо я, кажется, малость не понимаю: И зачем rol eax, cl в самом начале, когда не проверен первый байт? И вообще я не согласен с bts edx, eax когда в eax биты кроме тех что содержатся в al не пусты.
Black_mirror На выходе не восстанавливает mm0..mm2, flags. Возвращаемые значения неумышленно противоположны: 0 <-> -1 - используйте Код (Text): not eax jz ... Код (Text): format pe gui 4.0 include 'win32a.inc' section '' code import readable writable executable library kernel32,'kernel32.dll' include 'api\kernel32.inc' entry $ stdcall p1,$1234abcd,$10000000 invoke ExitProcess,0 proc p1; v1,v2 mov eax,[esp+4] movd mm0,eax shr eax,4 movd mm1,eax punpcklbw mm0,mm1 mov eax,[esp+8] movd mm1,eax shr eax,4 movd mm2,eax punpcklbw mm1,mm2 ;push $0f0f0f0f $0f0f0f0f ;pand mm0,[esp] ;pand mm1,[esp] ;add esp,8 pcmpeqb mm0,mm1 movq [esp+4],mm0 movd eax,mm0 or eax,[esp+8] jz .done or eax,-1 .done: ret 8 endp