Команды условного перехода
Общий вид команды:
[Метка] Код метка
Косвенный условный переход не используется. При трансляции команды вместо метки записывается разность между адресом метки и адресом очередной после команды условного перехода команды. Если эта разность помещается в один байт (-128.. 127) команда называется короткой (short). Для команд с ссылкой назад компилятор определяет тип команды сам. Для ссылок назад тип задается программистом, если не задан, принимается обычным. Если программист задал короткий переход, а он невозможен, компилятор выводит сообщение: RELATIVE JUMP OUT OF RANGE
Команды перехода делятся на переходы по флагам, переходы для знаковых и беззнаковых данных.
Таблица 6.1 Команды условного перехода
Переходы по флагам | Переходы для знаковых данных | Переходы для беззнаковых данных | |||||||||
Прямой | Обратный | Прямой | Обратный | Прямой | Обратный | ||||||
Jc | jnc | Jl (<) | Jnl (>=) | Jb(<) | Jnb(>=) | ||||||
Jp | jnp | Jle (<=) | Jnle(>) | Jbe(<=) | Jnbe(>) | ||||||
Jz | jnz | Je (==) | Jne(!=) | Je(==) | Jne(!=) | ||||||
Js | jns | Jg (>) | Jng (<=) | Ja (>) | Jna(<=) | ||||||
Jo | jno | Jge(>=) | Jnge (<) | jae(>=) | jnae(<) |
Примеры использования команд.
1. Составить программу для вычисления максимального из двух заданных чисел длиной 32 бита (числа со знаком).
Ideal
P586
Model flat
Extrn ExitProcess:proc
Dataseg
X dd 6
Y dd 7
Z dd ?
Codeseg
Begin: mov eax, [X]
Cmp eax, [Y]
Jge short m1
Mov eax, [Y]
M1:
Mov [Z], eax
End begin
2. Составить программу для вычисления минимального для двух 64 беззнаковых чисел.
X dd 0fefefefeh, 0ffffffffh
Y dd 0ffffffffffh, 0ffffffffh
Z dd ?,?
;Пусть сначала заданы младшая, а затем старшая цифра.
Mov eax, [X+4]
Cmp eax, [Y+4]
Ja mx
Jb my
Mov eax, [X]Cmp eax, [Y]
Jae mx
My:
Mov eax, [Y]
Mov [Z], eax
Mov eax, [Y+4]
Mov [Z+4], eax
Jmp short m1
Mx:
Mov eax, [X]
Mov [X], eax
Mov eax, [X+4]
Mov [X+4], eax
M1:
Пример 3.
Скопировать данные из одной области памяти в другую, если заданы адреса обеих областей и размер
Addr1 dd …
Addr2 dd …
Len dd …
Способ 1
Mov eax, [addr1]
Mov edx, eax
Add edx, [len]
Mov ebx, [addr2]
For1:
Mov cl, [eax]
Mov [ebx], cl
Inc eax
Inc ebx
Cmp eax, edx
Jle for1
…
Ошибка!: команду Jle необходимо заменить командой для сравнения чисел без знака! (Jbe).
Недостаток решения! Не учтено возможное перекрытие областей!
Способ 2
Ab = addr1; h = 1; Be = addr2;
If (addr2 != addr1){
If (addr2 > addr1 && addr2 < addr1+len){
Ab += len – 1; Bb +=len – 1;
H=-1;
}
for (i=0; i<len; i++){
*Bb = *Ab
bb+=h;
aa+=h;
}
;Ab = addr1; h = 1; Be = addr2;
mov eax, [addr1]
mov ebx, [addr2]
mov edx, 1
;If (addr2 != addr1){
cmp eax, ebx
je short break
; If (addr2 > addr1 && addr2 < addr1+len){
cmp eax, ebx
jbe m1
mov ecx, eax
add ecx, [len]
cmp ebx, ecx
jae m1
;Ab += len – 1; Bb += len – 1; H=-1;
mov eax, ecx
dec eax
add ebx, [len]
dec ebx
mov edx, -1
;}
;for (i=0; i<len; i++){ *Bb = *Ab; bb+=h; aa+=h;
mov esi, [len]
for2:
mov cl, [eax]
mov [ebx], cl
add eax, edx
add ebx, edx
sub esi, 1
jnz for2