Участник:GeraltFromRivia/Лекция асм 04

Материал из Викиконспекты
< Участник:GeraltFromRivia
Версия от 15:26, 28 июня 2012; GeraltFromRivia (обсуждение | вклад) (Новая страница: «;!! IF !! thiscall ecx +stdcall f(a, b, c); a -> f(b, c); push c push b push a call f либо push a push buff call f ret esp, 4 f: mov ecx, [exp + 5]...»)
(разн.) ← Предыдущая | Текущая версия (разн.) | Следующая → (разн.)
Перейти к: навигация, поиск
!! IF  !!

thiscall ecx +stdcall

f(a, b, c); a -> f(b, c);

push c push b push a call f

либо

push a push buff call f ret esp, 4

f: mov ecx, [exp + 5] mov [ecx], ... mov eax ecx ret 4

-------------------------------------------------------

if (eax < 5) ...1 else ...2

то же самое, что и:

cmp eax, 5 JAE l1 ;беззнаковое сравнение jump ... equal ...1 JMP l2 l1: ...2 l2: ...

-------------------------------------------------------

if (eax < 5 && ebx) ...1 else ...2

то же самое, что и:

cmp eax, 5 JAE l1 test ebx, ebx JNZ l1 ...1 JMP l2 l1: ...2 l2: ...

--------------------------------------------------------

Если ebx заменить на [ebx] то все может полететь, надо быть на готове

сделаем теперь такое:

if (eax > '0' && ebx <= '9') ...1

то же самое, что и:

lea ecx, [eax - '0'] ;трехоперандное вычитание cmp ecx, '9' - '0' JA l1 ;работает с беззнаковыми числами, переход по адресу ... l1: ...

заметим, что компилятор очень часто именно так и переводит

код нуля '0' представляется в виде 0x30 ... код девятки '9' представляется как 0x39

но у нас есть целый промежуток от 0x00 до 0xFF

поэтому мы хотим сделать сдвиг влево на 30, тогда первые 30 значений "уйдут в правый конец"

if ((uint)(eax - '0') <= '9'-'0')

char нам знаковость не гарантирует, поэтому с ним аккуратнее(его не с амортизировали)

----------------------------------------------------------
   int

if (eax > '0' && ebx <= '9') ...1

то же самое, что и:

lea ecx, [eax - '0'] ; sub eax, '0' cmp ecx, '9' - '0' JA l1 ... l1: ...

-------------------------------------------------------------

5) MOV eax, 1 2) xoc eax, eax 1) inc eax,

=============================================================
!! SWITCH  !!

switch(eax) { case 1: ...1 break; case 3: case 4: ...2 default ...3 }

реализуется так:

table dd l3, l1, l3, l2, l2 ;находится в сегменте данных для чтения

CMP eax, 4 JA l3 JMP dword [table + eax + 4] ;dword = double word l1: ...1 JMP l4 l2: ...2 l3: ...3 l4: ...4

=======================================================================
!! WHILE !!

задачка - реализовать while (eax > 3) ...;

l1: cmp eax, 3 JBE l2 ;jump belong to equal ...1 JMP l1 l2: ...2

------------------------------------------------------------------

задачка - реализовать do ... while (eax > 3)

l1: ...1 cmp eax, 3 JA l1

заметим, что во втором случае, у нас и конструкция легче, и кода меньше(проще) как модифицировать while, чтоьы по эффективности он догнал do...while?

CMP eax, 3 JBE 12 l1: cmp eax, 3 JA l1 l2:

=============================================================================
!! FOR  !!

for (uint eax = 0; eax < 5; eax++) ;uint = unsigned integer {...}


XOR eax, eax l1: ... inc eax emp eax, 5 JB l1

----------------------------------------------------------------------------

for (uint eax = 4; eax >= 0; eax--) {...}


mov eax, 4 l1: ... SUB eax, 1 JNC l1