Участник:GeraltFromRivia/Лекция асм 04 — различия между версиями
(Новая страница: «;!! 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]...») |
|||
| Строка 4: | Строка 4: | ||
ecx +stdcall | ecx +stdcall | ||
| − | f(a, b, c); | + | f(a, b, c); |
| − | a -> f(b, c); | + | a -> f(b, c); |
| − | push c | + | push c |
| − | push b | + | push b |
| − | push a | + | push a |
| − | call f | + | call f |
либо | либо | ||
| − | push a | + | push a |
| − | push buff | + | push buff |
| − | call f | + | call f |
| − | ret esp, 4 | + | ret esp, 4 |
| − | f: | + | f: |
| − | + | mov ecx, [exp + 5] | |
| − | + | mov [ecx], ... | |
| − | + | mov eax ecx | |
| − | + | ret 4 | |
;;------------------------------------------------------- | ;;------------------------------------------------------- | ||
| − | if (eax < 5) | + | if (eax < 5) |
| − | + | ...1 | |
| − | else | + | else |
| − | + | ...2 | |
то же самое, что и: | то же самое, что и: | ||
| − | + | cmp eax, 5 | |
| − | + | JAE l1 ;беззнаковое сравнение jump ... equal | |
| − | + | ...1 | |
| − | + | JMP l2 | |
| − | l1: | + | l1: |
| − | + | ...2 | |
| − | l2: | + | l2: |
| − | + | ... | |
;;------------------------------------------------------- | ;;------------------------------------------------------- | ||
| − | if (eax < 5 && ebx) | + | if (eax < 5 && ebx) |
| − | + | ...1 | |
| − | else | + | else |
| − | + | ...2 | |
то же самое, что и: | то же самое, что и: | ||
| − | + | cmp eax, 5 | |
| − | + | JAE l1 | |
| − | + | test ebx, ebx | |
| − | + | JNZ l1 | |
| − | + | ...1 | |
| − | + | JMP l2 | |
| − | l1: | + | l1: |
| − | + | ...2 | |
| − | l2: | + | l2: |
| − | + | ... | |
;;-------------------------------------------------------- | ;;-------------------------------------------------------- | ||
| − | Если ebx заменить на [ebx] то все может полететь, надо быть на готове | + | Если ebx заменить на [ebx] то все может полететь, надо быть на готове сделаем теперь такое: |
| − | + | if (eax > '0' && ebx <= '9') | |
| − | + | ...1 | |
| − | if (eax > '0' && ebx <= '9') | ||
| − | |||
то же самое, что и: | то же самое, что и: | ||
| − | + | lea ecx, [eax - '0'] ;трехоперандное вычитание | |
| − | + | cmp ecx, '9' - '0' | |
| − | + | JA l1 ;работает с беззнаковыми числами, переход по адресу | |
| − | + | ... | |
| − | l1: | + | l1: |
| − | + | ... | |
заметим, что компилятор очень часто именно так и переводит | заметим, что компилятор очень часто именно так и переводит | ||
| Строка 79: | Строка 77: | ||
код нуля '0' представляется в виде 0x30 | код нуля '0' представляется в виде 0x30 | ||
... | ... | ||
| + | |||
код девятки '9' представляется как 0x39 | код девятки '9' представляется как 0x39 | ||
| Строка 89: | Строка 88: | ||
char нам знаковость не гарантирует, поэтому с ним аккуратнее(его не с амортизировали) | char нам знаковость не гарантирует, поэтому с ним аккуратнее(его не с амортизировали) | ||
;;---------------------------------------------------------- | ;;---------------------------------------------------------- | ||
| − | + | int | |
| − | if (eax > '0' && ebx <= '9') | + | if (eax > '0' && ebx <= '9') |
| − | + | ...1 | |
то же самое, что и: | то же самое, что и: | ||
| − | + | lea ecx, [eax - '0'] | |
| − | + | ; sub eax, '0' | |
| − | + | cmp ecx, '9' - '0' | |
| − | + | JA l1 | |
| − | + | ... | |
| − | l1: | + | l1: |
| − | + | ... | |
;;------------------------------------------------------------- | ;;------------------------------------------------------------- | ||
| − | 5) MOV eax, 1 | + | 5) MOV eax, 1 |
| − | 2) xoc eax, eax | + | 2) xoc eax, eax |
| − | 1) inc eax, | + | 1) inc eax, |
;;============================================================= | ;;============================================================= | ||
;!! SWITCH !! | ;!! SWITCH !! | ||
| − | switch(eax) | + | switch(eax) |
| − | { | + | { |
| − | case 1: | + | case 1: |
| − | + | ...1 | |
| − | + | break; | |
| − | case 3: | + | case 3: |
| − | case 4: | + | case 4: |
| − | + | ...2 | |
| − | default | + | default |
| − | + | ...3 | |
| − | } | + | } |
реализуется так: | реализуется так: | ||
| − | table dd l3, l1, l3, l2, l2 ;находится в сегменте данных для чтения | + | table dd l3, l1, l3, l2, l2 ;находится в сегменте данных для чтения |
| − | + | ||
| − | + | CMP eax, 4 | |
| − | + | JA l3 | |
| − | + | JMP dword [table + eax + 4] ;dword = double word | |
| − | l1: | + | l1: |
| − | + | ...1 | |
| − | + | JMP l4 | |
| − | l2: | + | l2: |
| − | + | ...2 | |
| − | l3: | + | l3: |
| − | + | ...3 | |
| − | l4: | + | l4: |
| − | + | ...4 | |
;;======================================================================= | ;;======================================================================= | ||
| Строка 143: | Строка 142: | ||
задачка - реализовать while (eax > 3) ...; | задачка - реализовать while (eax > 3) ...; | ||
| − | l1: | + | l1: |
| − | + | cmp eax, 3 | |
| − | + | JBE l2 ;jump belong to equal | |
| − | + | ...1 | |
| − | + | JMP l1 | |
| − | l2: | + | l2: |
| − | + | ...2 | |
;;------------------------------------------------------------------ | ;;------------------------------------------------------------------ | ||
задачка - реализовать do ... while (eax > 3) | задачка - реализовать do ... while (eax > 3) | ||
| − | l1: | + | l1: |
| − | + | ...1 | |
| − | + | cmp eax, 3 | |
| − | + | JA l1 | |
заметим, что во втором случае, у нас и конструкция легче, и кода меньше(проще) | заметим, что во втором случае, у нас и конструкция легче, и кода меньше(проще) | ||
как модифицировать while, чтоьы по эффективности он догнал do...while? | как модифицировать while, чтоьы по эффективности он догнал do...while? | ||
| − | + | CMP eax, 3 | |
| − | + | JBE 12 | |
| − | l1: | + | l1: |
| − | + | cmp eax, 3 | |
| − | + | JA l1 | |
| − | l2: | + | l2: |
| − | + | ||
;;============================================================================= | ;;============================================================================= | ||
;!! FOR !! | ;!! FOR !! | ||
| − | for (uint eax = 0; eax < 5; eax++) ;uint = unsigned integer | + | for (uint eax = 0; eax < 5; eax++) ;uint = unsigned integer |
| − | {...} | + | {...} |
| − | + | XOR eax, eax | |
| − | l1: | + | l1: |
| − | + | ... | |
| − | + | inc eax | |
| − | + | emp eax, 5 | |
| − | + | JB l1 | |
;;---------------------------------------------------------------------------- | ;;---------------------------------------------------------------------------- | ||
| − | for (uint eax = 4; eax >= 0; eax--) | + | for (uint eax = 4; eax >= 0; eax--) |
| − | {...} | + | {...} |
| − | + | mov eax, 4 | |
| − | l1: | + | l1: |
| − | + | ... | |
| − | + | SUB eax, 1 | |
| − | + | JNC l1 | |
Текущая версия на 15:30, 28 июня 2012
- !! 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