189
правок
Изменения
Новая страница: «;!! 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
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