Участник: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