23 способа получить в регистре единицу.

Discussion in 'С/С++, C#, Rust, Swift, Go, Java, Perl, Ruby' started by 0x0c0de, 3 Oct 2007.

  1. 0x0c0de

    0x0c0de Elder - Старейшина

    Joined:
    25 May 2007
    Messages:
    441
    Likes Received:
    396
    Reputations:
    297
    23 способа получить в регистре единицу.
    От самых простых до самых извратных. Хорошая разминка для мозгов.

    1. непохек
    Code:
     
    mov eax,1.
    
    Просто положить в регистр единицу

    2.
    Code:
    sub eax,eax /xor eax,eax (по отдельности не рассматриваю)
       inc eax
    
    Красиво, довольно коротко. Обнуляем, инкрементируем....

    3.
    Code:
     imul eax,0
        inc eax
    Тоже красиво. Обнуляем, инкрементируем

    4. Сопроцессор, но тут нужна дополнительная переменная. mem dword ?
    Code:
    finit
    fld1
    fist mem
    mov eax,mem
    
    в eax - теперь 1
    Сначала мы инициализируем сопроцессор (finit), потом загружаем в st0 1, потом отправляем
    содержимое st0 в mem, mem ложим в eax )

    5. Еще сопроцессор ( mem dword ?)
    Code:
    finit
    fldpi
    fcos
    fchs
    fist mem
    mov eax,mem
    
    То есть ложим в st0 число пи, находим косинус пи (-1), меняем знак, сохраняем значение

    6. А теперь больше тригонометрии
    Code:
    finit
    fldz
    fcos
    fist mem
    mov eax,mem
    
    Ищем косинус от нуля))))) А это 1)))

    7. А еще можно так
    Code:
     sub eax,eax
     sub al,-1
    
    это 4 байта.

    8. Самый мой любимый способ
    Code:
    sub eax,eax
    bfs eax,0
    
    В нулевой бит ложим 1=)

    9.
    Code:
     lea eax,[1]
    Длинно, но все же....

    10. Разновидность 5 метода, но беру модуль
    Code:
    finit
    fldpi
    fcos
    fabs
    fist mem
    mov eax,mem
    
    11.
    Code:
    sub eax,eax
       dec eax
       imul eax,eax
    Ну это всем наверное ясно -1*(-1)=1

    12. Этот способ я тоже люблю.
    Делим двоичный логарифм 10 сам на себя.Аналогичный способ с любым др. числом (например с натуральным логарифмом 2 -
    оба способа рассматриваются)
    Code:
    finit
    fld2t
    fld2t
    fdiv st0,st1
    fist mem
    mov eax,mem
    
    и соответственно

    Code:
    finit
    fldln2
    fldln2
    fdiv st0,st1
    fist mem
    mov eax,mem
    
    а можно еще с числом пи и десятичным логарифмом 2
    Code:
    finit
    fldpi
    fldpi
    fdiv st0,st1
    fist mem
    mov eax,mem
    
    и

    Code:
    finit
    fldlg2
    fldlg2
    fdiv st0,st1
    fist mem
    mov eax,mem
    
    13. Тригонометрия. Что-то меня тригонометрия в последнее время вдохновляет. Вариация на тему основного тригонометрического
    тождества.
    Code:
    finit
    fldln2 ; натуральный логарифм 2
    fcos ; получаем косинус
    fldln2
    fcos 
    fmul st,st(1) ; (cos(ln2))^2
    fldln2 
    fsin ; теперь синус 
    fldln2
    fsin
    fmul st(1),st ; (sin(ln2))^2
    fincstp 
    fadd st,st(1) ; st0+st1=1 по основному тригонометрическому тождеству 
    fist mem
    
    14. Красивый способ
    Code:
    stc ; установка флага переноса в 1
    sbb eax,eax ; вычитание с заемом
    neg eax ; -(-1)=1
    
    15. В еax будет true, то есть 1
    Code:
    sub eax,eax
    cmp eax,eax
    sete al
    
    16. Еще извратный способ
    Code:
    sub eax,eax
    sub ecx,ecx
    dec eax
    mov cx,1fh
    m1:
    btc eax,ecx ; фишка в этой команде. инвертируем все биты, кроме последнего, тогда в самом регистре будет 1
    loop m1
    
    17.А еще можно так
    Code:
    sub eax,eax
    stc ; установка флага переноса в 1
    adc eax,eax ; сложнение с учетом флага переноса CF
    
    18.Простенько, но со вкусом
    Code:
    sub eax,eax
    or eax,1
    
    19. Почти тоже самое
    Code:
     
    xor eax,eax
    xor eax,1
    
    20.Обалденный способ. 4 bsr над -1 и получаем 1)
    Code:
       sub eax,eax
       dec eax
       bsr eax,eax
       bsr eax,eax
       bsr eax,eax
       bsr eax,eax
    
    21. Тоже вариант
    Code:
     sub eax,eax
     dec eax
     shr eax,1fh ; логический сдвиг вправо
    
    22. Скушный метод, но результат тот же
    Code:
    xor eax,eax
    dec eax
    and eax,1
    
    23. Довольно неинтересно.. но все же
    Code:
    xor eax,eax
    dec eax
    neg eax
    
    Пока на этом все......
     
    #1 0x0c0de, 3 Oct 2007
    Last edited: 3 Oct 2007
    9 people like this.
  2. Ni0x

    Ni0x Elder - Старейшина

    Joined:
    27 Aug 2006
    Messages:
    338
    Likes Received:
    157
    Reputations:
    37
    Это все конечно круто, только зачем мне куча каких-то извращенных способов, если обычно используются 3-4 способа из списка? Причем по размеру они выигравают все остальные. Честно говоря, похоже на детское хвастовство, теперь сделай 23 способа как получить -1 в регистре. Без обид, но лучше вкладывать свой потенциал во что-то более серьезное.
     
  3. 0x0c0de

    0x0c0de Elder - Старейшина

    Joined:
    25 May 2007
    Messages:
    441
    Likes Received:
    396
    Reputations:
    297
    Ну цель вообще другая была... А именно
    Выйти за рамки стандартных команд так сказать. Я таким образом после дня напряженной учебы расслабляюсь

    думаю их больше... тоже мысль.

    ЗЫ Ясное дело, что лучше всего

    Code:
     
    sub eax,eax
    inc eax
    
    это всего 3 байта. Но юзают-то в основном mov eax,1
    а это 5 байт=\\\\ Так что материал полезен для общего развития)
     
    #3 0x0c0de, 3 Oct 2007
    Last edited: 3 Oct 2007
    2 people like this.
  4. Xserg

    Xserg Elder - Старейшина

    Joined:
    9 Dec 2006
    Messages:
    135
    Likes Received:
    127
    Reputations:
    53
    +7 до 30

    тоже 3 байта (константа до 255 для W32)
    Code:
    push 1
    pop eax
    с использованием API, которая обязательно возвратит 0
    Code:
    invoke IsWindow,-1
    inc eax
    ; неудобный метод
    Code:
    push 1
    push esp
    pop esi
    lodsd
    pop esi
    способ с исчезновением стека
    Code:
    stc ;<- 1
    pushfd
    xchg esi,esp
    lodsd 
    xchg esi,esp
    and eax,1
    мешает отладке
    Code:
      call @1
        dd 1
    @1: pop eax    
    mov eax,[eax]
    всего 11 байт запутанное зануление EAX
    Code:
    movzx ebx,ax
    xchg ebx,eax
    bswap eax
    movzx ebx,ax
    xchg ebx,eax
    inc eax
    полное извращение, но прикольно
    Code:
       call @2
    @2: pop esi
        push esi
        std
        lodsb
        sub [esp],esi
        cld
        pop eax
     
    2 people like this.
  5. dmnt

    dmnt Elder - Старейшина

    Joined:
    6 Jun 2007
    Messages:
    89
    Likes Received:
    36
    Reputations:
    15
    вы таки шеллкодесов не писали
    тут есть таки разница что использовать
     
  6. nerezus

    nerezus Banned

    Joined:
    12 Aug 2004
    Messages:
    3,191
    Likes Received:
    729
    Reputations:
    266
    Так он понятнее. Понятность кода намного важнее размера и скорости ) Есть конечно пара исключений, но это редкость.
     
  7. Piflit

    Piflit Banned

    Joined:
    11 Aug 2006
    Messages:
    1,249
    Likes Received:
    585
    Reputations:
    31
    -1. для понятности существуют комментарии
     
    3 people like this.
  8. Hellsp@wn

    Hellsp@wn Elder - Старейшина

    Joined:
    29 Apr 2007
    Messages:
    401
    Likes Received:
    153
    Reputations:
    48
    ещё так... тока мсысл всего этого? =) нету...

    Xor eax,eax
    Mov Al,1
     
  9. Forcer

    Forcer Elder - Старейшина

    Joined:
    12 Apr 2007
    Messages:
    321
    Likes Received:
    98
    Reputations:
    12
    А я наоборот, полностью согласен с nerezus. Скорость, быстродействие - зависит от скила кодера в данный момент времени. А вот понятность кода, возможность его модернизации - это, так сказать, на все времена! Но это отнюдь не означает, что надо писать медленный и алгоритмически неправильный код в ушерб понятности. надо знать меру : ). По теме: асм не знаю, заметил лишь одно: не "ложим", а "кладем" - рус.яз. рулит : )
     
  10. 0x0c0de

    0x0c0de Elder - Старейшина

    Joined:
    25 May 2007
    Messages:
    441
    Likes Received:
    396
    Reputations:
    297
    Клево. "Кладем"... Важное замечание такое)))))))))
    В чем смысл? Я уже писала в чем смысл.... в далеком октябре. Читаем пост номер 1 вторая строка второе предложение. Читаем пост номер три. ЦЕЛИКОМ.

    нууууууу))))))) ну ладно... пусть будет. 31-й.
     
    1 person likes this.
  11. Jes

    Jes Elder - Старейшина

    Joined:
    16 Apr 2007
    Messages:
    370
    Likes Received:
    391
    Reputations:
    34
    Мой код эффективнее :D :D :D
    Code:
    .386 
    .model flat, stdcall 
    ExitProcess PROTO      ,:DWORD 
    MessageBoxA PROTO      ,:DWORD, :DWORD, :DWORD, :DWORD 
    .data 
       MsgBoxCaption  db "Внимание",0 
       MsgBoxText     db "Нажмите пожалуйста клавишу A(обязательно с шифтом, а то прога заглючит нах)",0 
    .const 
       NULL        equ  0 
       MB_OK    equ  0 
    .code 
       Main: 
        INVOKE    MessageBoxA, NULL, ADDR MsgBoxText, ADDR MsgBoxCaption, MB_OK 
    
    h
    AX=0168  BX=0000  CX=0000  DX=0000  SP=FFEE  BP=0000  SI=0000  DI=0000
    DS=0ABD  ES=0ABD  SS=0ABD  CS=0ABD  IP=0102   NV UP EI PL NZ NA PO NC
    0ABD:0102 96            XCHG    SI,AX
    -
        INVOKE    ExitProcess, NULL 
       end Main 
     
  12. DWORD

    DWORD Elder - Старейшина

    Joined:
    24 Jul 2007
    Messages:
    129
    Likes Received:
    70
    Reputations:
    -36
    Для этого есть "высокоуровневый ассемблер" - лучший язык в мире С. Ассемблер нужно использовать только там, где без него нельзя обойтись и можно использовать для оптимизации кода, ни о какой понятности кода речь не идет.
     
    1 person likes this.
  13. desTiny

    desTiny Elder - Старейшина

    Joined:
    4 Feb 2007
    Messages:
    1,006
    Likes Received:
    444
    Reputations:
    94
    а зачем писать fdiv st0,st1 когда проще fdivp?
     
  14. 0x0c0de

    0x0c0de Elder - Старейшина

    Joined:
    25 May 2007
    Messages:
    441
    Likes Received:
    396
    Reputations:
    297
    >> а зачем писать fdiv st0,st1 когда проще fdivp?

    а вы предлагайте новые способы, не стесняйтесь. Следуйте примеру Xserg) Здесь я и не думала писать, что проще. Просто рассмотрела пару десятков извратных способов. mov eax,1 - это было весьма скушно.
    Приятно, что тема не умерла и кому-то это еще интересно.
     
    1 person likes this.
  15. Delimiter

    Delimiter Banned

    Joined:
    8 Apr 2005
    Messages:
    317
    Likes Received:
    173
    Reputations:
    12
    либо ослеп .... либо туплю!
    не увидел банального
    ...
    mov ax,256
    xchg ah,al
    ...
     
  16. zl0y

    zl0y Banned

    Joined:
    13 Sep 2006
    Messages:
    371
    Likes Received:
    270
    Reputations:
    109
    xor ecx,ecx
    jecxz m
    @m:
    inc ecx

    :)

    вот только что еще пришло в голову

    с loop

    .....
    @m:
    loop m
    .....
    суть в том,что если надо обнулить ecx,то как раз будет цикл пока в ecx не будет 0,после чего можно inc ecx по желанию :)
     
    #16 zl0y, 21 Jan 2008
    Last edited: 21 Jan 2008
  17. Delimiter

    Delimiter Banned

    Joined:
    8 Apr 2005
    Messages:
    317
    Likes Received:
    173
    Reputations:
    12
    хммммммм..... лупы пошли 8)))

    mov ecx,3
    mov eax,7
    a: sub ax,cx
    loop a
     
  18. ZaCo

    ZaCo Banned

    Joined:
    20 Jun 2005
    Messages:
    737
    Likes Received:
    336
    Reputations:
    215
    я теперь понял еще одно отличие кодера с античата (хэкера) от программиста: программист не будет искать еще один способ получить в регистре 1, и тем более через жопу, тогда как кодер с античата следуя манифесту хэкера задействует все самые бесполезные инструкции. что ж вы еще системные вызовы не подключили, по-моему супер это записать 1 на диск и считать ее же в регистр. 0x0c0de бездельник и тунеядец! эхх...
     
    3 people like this.
  19. zl0y

    zl0y Banned

    Joined:
    13 Sep 2006
    Messages:
    371
    Likes Received:
    270
    Reputations:
    109
    Еще боюсь,что можно shr,shl

    идея пришла вобще то давно )
    shr eax,33 - 1 байт 8 бит - макс значение в 32 битном регистре(DWORD = 4 байтам или 32 бита),следовательно сдвинув регистр на 33 мы получим 0 :)
     
  20. KEZ

    KEZ Ненасытный школьник

    Joined:
    18 May 2005
    Messages:
    1,604
    Likes Received:
    754
    Reputations:
    397
    Ещё можно сделать так. Запустить netcat на удаленном unix-хосте взломаном, приконектится со своего компа туда telnet'ом и послать единицу, а там руткит перехватит её в траффике, преобразует в число и засунет в регистр. Заодно потом в консоли можно на ascii-порнуху подрочить, за заслуги, как все настоящии хакеры по манифесту (вместо стандарта).
     
    4 people like this.