Программирование на Ассемблере

       

Команды условного перехода


Общий вид команды:

[Метка]         Код     метка

Косвенный условный переход не используется. При трансляции команды вместо метки записывается разность между адресом метки и адресом очередной после команды условного перехода команды. Если эта разность помещается в один байт (-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
Содержание раздела