Мелкие задачки для крупных мозгов №26

Тема в разделе "WASM.A&O", создана пользователем Black_mirror, 27 июн 2006.

  1. Black_mirror

    Black_mirror Active Member

    Публикаций:
    0
    Регистрация:
    14 окт 2002
    Сообщения:
    1.035
    В регистрах EAX,ECX,EBX,EDX находятся неотрицательные числа от 0 до 2^32-1, которые задают два множества A=[EAX..ECX) и B=[EBX..EDX). Левая(меньшая) граница принадлежит множеству, а правая(большая) нет. Например, множество [4..7) состоит из 3х чисел: 4,5 и 6. Необходимо написать три функции, которые в регистр EAX поместят количество чисел в объединениии(OR), пересечении(AND) и симметричной разности(XOR) множеств A и B соответственно.



    Пример:

    A=[5..15)

    B=[10..20)

    Объединение=[5..20) и содержит 15 чисел.

    Пересечение=[10..15) и содержит 5 чисел.

    Сим.Разность=[5..10)+[15..20) и содержит 10 чисел.



    Забыл одно важное условие: код конечно же должен быть без переходов ;)
     
  2. Boola

    Boola New Member

    Публикаций:
    0
    Регистрация:
    28 дек 2004
    Сообщения:
    24
    Адрес:
    Russia
    Объеденение - 47 байт

    Пересечение - 43 байта

    Сим.Разность - 51 байт



    Начало общее для всех функций (34 байта)



    mov esi, eax

    mov edi, ecx

    cmp eax, ebx

    cmovnc esi, ebx

    cmovnc edi, edx

    cmovnc ebx, eax

    cmovnc edx, ecx

    mov eax, esi

    mov ecx, edi



    mov esi, ecx

    cmp ecx, edx

    cmovnc esi, edx

    cmovnc edx, ecx

    mov ecx, esi



    Далее отделное окончание для каждой функции

    ~~~~~or~~~~~ - 13+22= 47 байтов

    sub edx, eax

    xor esi, esi

    sub ebx, ecx

    cmovnc esi, ebx

    sub edx, esi

    mov eax, edx



    ~~~~~and~~~~~ - 9+22= 43 байта

    xor esi, esi

    sub ecx, ebx

    cmovc ecx, esi

    mov eax, ecx



    ~~~~~xor~~~~ - 17+22= 51 байт

    sub edx, eax

    xor esi, esi

    sub ebx, ecx

    cmovc esi, ebx

    sub edx, ebx

    add edx, esi

    add edx, esi

    mov eax, edx
     
  3. asd

    asd New Member

    Публикаций:
    0
    Регистрация:
    12 мар 2005
    Сообщения:
    952
    Адрес:
    Russia
    Я о таких командах не слышал даже.


    Код (Text):
    1. or 57 байт
    2.     xor esi,esi
    3.     cmp ebx,ecx
    4.     rcl esi,1
    5.     cmp ebx,eax
    6.     rcl esi,1
    7.     cmp edx,ecx
    8.     rcl esi,1
    9.     cmp edx,eax
    10.     rcl esi,1
    11.     push eax
    12.     movzx eax,byte ptr [command_table+esi]
    13.     shl eax,2
    14.     shr al,2
    15.     or word ptr[command],ax
    16.     jmp get_result
    17. command_table:
    18. @0  db  0dbh    ;11 01 1 011    ebx,ebx,ebx
    19.  
    20. get_result:
    21. @1  db  58h ;pop eax
    22. @2  db  2bh ;sub
    23. command db  0c0h    ;mod r/m (sub)
    24. push_   db  50h ;push
    25. @5  db  58h ;pop eax
    26. @6  db  0ebh    ;jmp
    27. @7  db  8   ;jmp range прыжок на end_
    28. @8  db  4bh ;01 00 1 011    ecx,ecx,ebx
    29. @9  db  ?
    30. @a  db  93h ;10 01 0 011    edx,edx,ebx
    31. @b_ db  ?
    32. @c  db  48h ;01 00 1 000    ecx,ecx,eax
    33. @d  db  ?
    34. @e  db  90h ;10 01 0 000    edx,edx,eax
    35. @f_ db  0dbh    ;11 01 1 011    ebx,ebx,ebx
    36. end_:
    37. -----------------------------------




    and: or+ то,что ниже
    Код (Text):
    1.     mov ebp,edx
    2.     sub ebp,ebx
    3.     add ebp,ecx
    4.     sub ebp,eax
    5.        здесь or
    6.     sub eax,ebp
    7.     neg eax




    xor: or+ то,что ниже
    Код (Text):
    1.     mov ebp,edx
    2.     sub ebp,ebx
    3.     add ebp,ecx
    4.     sub ebp,eax
    5.        здесь or
    6.         shl eax,1
    7.     sub eax,ebp
    8.     neg eax
     
  4. Black_mirror

    Black_mirror Active Member

    Публикаций:
    0
    Регистрация:
    14 окт 2002
    Сообщения:
    1.035
    В лоб у меня получается:

    AND - 24 байта

    OR - 34 байта

    XOR - 37 байт



    Но решения пока публиковать не буду, сделаю только пару подсказок. Вот как можно вычислить максимум и минимум двух чисел:

    D=A-B

    M=SBB M,M

    D=D AND M

    A=A-D ;MAX(A,B)

    B=B+D ;MIN(A,B)

    Чтобы вычислить сколько чисел в пересечении множеств можно из MIN(ECX,EDX) вычесть MAX(EAX,EBX) и если возникло переполнение - обнулить результат.
     
  5. B_108

    B_108 New Member

    Публикаций:
    0
    Регистрация:
    5 окт 2003
    Сообщения:
    62
    Вычисление OR, 33 байта, немного оптимизированный "в лоб" :)
    Код (Text):
    1.  
    2.     ;eax..ecx == [A..C)
    3.     ;ebx..edx == [B..D)
    4.  
    5.     lea edi, [ecx+edx] ;C + D
    6.  
    7.     sub ecx, edx ;C == C - D
    8.     sbb esi, esi ;M == SBB M - M
    9.     and ecx, esi ;C == C & M
    10.     add ecx, edx ;C == C + D
    11.              ;C == min(C,D)
    12.  
    13.     sub edi, eax
    14.     sub edi, ebx ;X == (C + D) - A - B == (D - B) + (C - A) == сумма длин отрезков
    15.  
    16.              ;D (edx) больше не нужна, используем как временную переменную
    17.  
    18.     mov edx, ebx ;D == B
    19.     sub edx, eax ;D == B - A
    20.     sbb esi, esi ;M == SBB M - M
    21.     and edx, esi ;D == D & M
    22.     sub ebx, edx ;B == B - D
    23.              ;B == max(A,B)
    24.  
    25.     sub ebx, ecx ;max(A,B) - min(C,D)
    26.     sbb esi, esi
    27.     and ebx, esi ; == -ANDlength
    28.  
    29.     add edi, ebx ;{сумма длин отрезков} + (-ANDlength)
    30.              ; ==  {сумма длин отрезков} - ANDlength == ORlength
    31.  
     
  6. Boola

    Boola New Member

    Публикаций:
    0
    Регистрация:
    28 дек 2004
    Сообщения:
    24
    Адрес:
    Russia
    модификация варианта B_108 - 32 байта



    lea edi, [ecx+edx]

    xor esi, esi



    sub ecx, edx

    cmovnc ecx, esi

    add ecx, edx



    sub edi, eax

    sub edi, ebx



    mov edx, ebx

    sub edx, eax

    cmovnc edx, esi

    sub ebx, edx



    sub ebx, ecx

    cmovnc ebx, esi

    add edi, esi
     
  7. Boola

    Boola New Member

    Публикаций:
    0
    Регистрация:
    28 дек 2004
    Сообщения:
    24
    Адрес:
    Russia
    блин опечатка

    последняя команда

    add edi, ebx
     
  8. B_108

    B_108 New Member

    Публикаций:
    0
    Регистрация:
    5 окт 2003
    Сообщения:
    62
    для вычисление XOR если не ошибаюсь нужно из результата OR (ORlength) еще раз вычесть длину пересечения (ANDlength).



    То бишь в конце еще раз
    Код (Text):
    1.  
    2. add edi, ebx
    3.