Помогите с ассемблерным кодом - PullRequest
1 голос
/ 28 марта 2011
push eax 
push ecx 
and eax,0x3C 
ror eax,1 
ror eax,1 
inc eax 
mov edx,eax 
pop eax 
xor eax,edx 
pop ecx 
xor eax,ecx 
rol al,1 
ret 

Кто-нибудь может мне помочь понять, что делает этот код, комментируя его и почему мы делаем такие подпрограммы, как and и ror?Спасибо

Ответы [ 3 ]

3 голосов
/ 28 марта 2011

Этот код делает то же, что и:

unsigned int func(arg0, arg1)
{
    unsigned int tmp = (arg1 ^ (((arg0 & 0x3C) >> 2) + 1)) ^ arg0;
    unsigned char c = (unsigned char)(tmp & 0xff);
    return (tmp & ~0xff) | (unsigned int)((c << 7) | (c >> 1));
}

Если я все правильно прочитал, то есть. Весьма запутанный - откуда он?

В любом случае, для деталей:

Начните с: Из использования EAX / ECX в качестве аргументов видно, что при этом используется __fastcall соглашение о вызовах Microsoft (arg0 функции в EAX, arg1 в ECX).

Тогда просто следуйте арифметике до конца. Помимо последнего использования вращения только на AL, на самом деле все просто:

push eax         ; saves arg0 to stack
push ecx         ; saves arg1 to stack
and eax,0x3C     ; tmp = arg0 & 0x3C (this isolates bits 3-6, makes all else zero)
ror eax,1        ;
ror eax,1        ; twice rot right. Since upper bits are zero: tmp >>= 2;
inc eax          ; tmp++
mov edx,eax      ; EDX = tmp
pop eax          ; retrieve last item on stack, tmp2 = arg1
xor eax,edx      ; tmp2 ^= tmp;
pop ecx          ; retrieve prev item on stack, tmp3 = arg0
xor eax,ecx      ; tmp2 ^= tmp3
                 ;     full line: (arg1 ^ (((arg0 & 0x3C) >> 2) + 1)) ^ arg0
rol al,1         ; complex ... rotate lowest byte right by one
                 ;            al = (al >> 1) | (al << 7)
                 ; 
ret 

Edit: Zuljin дал мне идею здесь ... если функция на самом деле работает с байтами явно, то это можно сформулировать более простым способом:

char transmogrify(char arg0, char arg1)
{
    char tmp = (arg1 ^ (((arg0 << 2) >> 4) + 1))) ^ arg0;
    return ((tmp << 7) | (tmp >> 1));
}

Этот вид операции rotate(a ^ X ^ b, 1) используется как часть некоторых шифров, таких как DES, но то, что именно у вас есть, зависит от X (который здесь немного перемешан). Я не специалист по криптографии и не распознаю конкретный случай. Было бы интересно, если бы кто-то смог заполнить пробел в ...

1 голос
/ 28 марта 2011
push eax            ; pushing eax into stack
push ecx            ; pushing ecx into stack
and eax,0x3C        ; performs logical and operation on eax and 0x3C
ror eax,1           ; one bit right shift value from eax with carrying shifted bit to most significant bit (cyclic right shift)
ror eax,1           ; one bit right shift value from eax with carrying shifted bit to most significant bit (cyclic right shift)
inc eax         ; increment eax value
mov edx,eax         ; copy value from eax to edx
pop eax         ; restore eax value from stack, which was pushed by this command "push ecx"
xor eax,edx         ; exclusive or operation on eax and edx values
pop ecx         ; restore ecx value from stack, which was pushed by this command "push eax"
xor eax,ecx         ; exclusive or operation on eax and ecx values
rol al,1            ; one bit left shift value from al (least significant byte from eax) with carrying shifted bit to least significant bit (cyclic left shift)
ret             ; return from function

и я предлагаю вам прочитать некоторые статьи из https://stackoverflow.com/questions/199679/good-beginners-books-for-assembly-languages

0 голосов
/ 28 марта 2011
push eax - saves eax to stack
push ecx - saves ecx to stack
and eax,0x3C - logical AND register eax with 0x3c ( 111100 in binary) - this means that only 4 bits starting from bit 2 are interesting - in C : a = a & 

0x3C;
ror eax,1 - rotate one bit right - in C : a = a >> 1;
ror eax,1 - rotate one bit right - in C : a = a >> 1; so after this command these 4 interesting bits starting in position 0;
inc eax - increse these 4 bits value by one - in C : a++;
mov edx,eax - copy value from register eax to register edx
pop eax - load value from stack (value that was previously in ecx) and copy it to eax registry
xor eax,edx - xor value from stack(previously ecx) with incremented 4bits value - in C : b = b ^ a;
pop ecx - load value from stack (value that was previously in eax) and copy it to ecx registry
xor eax,ecx - xor value from stack(previously eax) once again - in C : c = c ^ b;
rol al,1 - rotate left by one bit the last byte (al) of registry eax - in C : c = (unsigned char)c << 1;
ret - return from function - probably this what is in EAX is a return value

Так более или менее так может выглядеть эта функция в C

unsigned char func1(unsigned int parm1, insigned int parm2)
{
  unsigned int a = par1 & 0x3C;
  a = a >> 1;
  a = a >> 1;
  a++;
  a = parm2 ^ a;
  a = parm1 ^ a;
  return (unsigned char)a << 1;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...