Tutorial Limbaj de Asamblare (Assembler) Intel 8086 – Partea 4 – Structuri de control

In acest tutorial destinat limbajului de asamblare pentru procesoare din familia Intel 8086 sunt prezentate structurile de control:

  • structura alternativa, sau structura IF
  • structura pre-conditionata, sau WHILE-DO
  • structura post-conditionata, sau DO-WHILE
  • structura alternativa multipla, sau CASE

Structura alternativa IF

In limbajele de nivel inalt structura de control alternativa este asociata cu expresia IF-THEN-ELSE. Implementarea structurii alternative presupune:

  • evaluarea unei expresii;
  • compararea a doua valori.

In ambele cazuri sunt initializate flag-urile de conditie, prezentate in partea I a tutorialului – Tutorial Limbaj de Asamblare (Assembler) Intel 8086 – Partea 1 – Elemente de baza.

Daca conditia evaluata este adevarata, atunci se executa secventa de instructiuni de pe ramura true; altfel expresiile de pe ramura false au prioritate.

In Assembler se utilizeaza pentru a compara doi operanzi instructiunile

  • CMP
  • CMPSB
  • CMPSW.

Tipuri de salturi in limbaj de asamblare

  • salturi neconditionate: JMP;
  • salturi conditionate: JA sau JNBE, JAE sau JNB, JB sau JNAE, JBE sau JNA, JC, JCXZ sau JECXZ, JE sau JZ, JG sau JNLE, JGE sau JNL, JL sau JNGE, JLE sau JNZ, JNC, JNE sau JNG, JNO, JNP sau JPO, LOOP, LOOPE sau LOOPZ, LOOPNE sau LOOPNZ.

Procesorul 8086 permite mai multe modalitati de a efectua un salt prin intermediul instructiunii jmp. Destinatia saltului poate fi in acelaşi segment (intrasegment) sau intr-un segment diferite (intersegment).

Tip jump

Forma interna

Jump intersegment 5 octeti: 1 pentru codul operatiei (EAh), 2 pentru offset şi 2 pentru adresa segment.
Jump intrasegment 3 octeti: 1 pentru codul operatiei (E9h), 2 pentru offset.
Jump-uri scurte (short jumps) 2 octeti: 1 pentru codul operatiei (EBh), 1 pentru a reprezenta o valoare cu semn aferenta offset-ului. In acest caz, destinatia trebuie sa fie intre +127 şi -128 de octeti fata de instructiunea de salt.
   

Instructiunea CMP

Flag-urile (descrise in Partea 1 – Elemente de baza) modificate de rezultatul instructiunii CMP sunt:

  • OF;
  • SF;
  • ZF;
  • AF;
  • PF;
  • CF;

Instructiunea CMP compara cei doi operanzi prin intermediul unei scaderi logice. Asta inseamna ca cei doi operanzi nu sunt modificati, insa bitii de flag sunt setati astfel incat sa indice rezultatul diferentei.

Exemplu de secventa de cod necesara compararii a doua valori intregi in limbaj de asamblare.

CMP DX, BX;
  • Cand BX = 0004 şi DX = 0008,

    DX – BX = 0004 (Atentie – aceasta scadere nu modifica operanzii)

    – nu are loc overflow (OF=0)

    – rezultatul este pozitiv (SF=0)

  • Cand BX = 000A şi DX = 0008,

    DX – BX = FFFE (- 2)

    – nu are loc overflow (OF=0)

    – negativ (SF=1)

Alte exemple pentru instructiunea assembler CMP

  • se considera registrele si valorile AX = 10, BX = -12 (decimal)
  • CMP AX, BX

AX – BX = +22

PL (positive, SF=0), CY (carry, CF=1), NV (no

Overflow, OF=0), NZ (not zero, ZF=0)

  • CMP BX, AX

BX – AX = -22

NG (negative, SF=1), NC (no carry, CF=0), NV (no

Overflow, OF=0), NZ (not zero, ZF=0)

  • CMP AX, AX

AX – AX = 0

PL (positive, SF=0), NC (no carry, CF=0;), NV (no

Overflow, OF=0), ZR (zero, ZF=1)

Ce putem compara?

  • registru cu registru: CMP AX, BX
  • registru cu memorie (variabile definite): CMP AX, mval
  • registru cu constante: CMP AX, 42
  • memorie cu registru: CMP mval, AX
  • memorie cu constanta (!) CMP mval, 42

Ce nu putem compara?

  • Nu se poate compara memorie cu memorie!!!
  • CMP a, b    ;instructiune gresita
  • Una dintre valori trebuie copiata intr-un registru inainte de a realiza comparatia.

Salturi conditionate

  • Salturile conditionate sunt utilizate pentru a trece la o alta locatie in segmentul de cod in fucntie de valorile anumitor biti de flag;
  • Numerele care sunt comparate pot reprezenta atat valori cu semn cat şi fara semn. Flag-uri diferite sunt verificate in functie de interpretarea valorilor.
  • Cum ştie procesorul cum interpreteaza utilizatorul valorile (fie cu semn, fie fara semn)?

Raspuns: in functie de tipul instructiunii de salt.

  • Salturi fara semn (valorile comparate sunt considerate fara semn) se refera prin cuvintele cheie “above” pentru mai mare şi “below” pentru mai mic.
  • Salturile cu semn se refera prin “greater” şi “less”.

Operatie

Instructiune de salt conditionat daca ambii operanzi sunt considerati fara semn

 

Instructiune de salt conditionat daca unul dintre operanzi este cu semn

<> or !=

JNE sau JNZ

 

JNE sau JNZ

= or ==

JE sau JZ

 

JE sau JZ

>=

JNB

 

JNL

>

JNBE sau JA

 

JNLE or JG

<=

JNA

 

JNG

<

JNAE sau JB

 

JNGE sau JL

Exemplu program assembler in care este evidentiata diferenta dintre Valori cu semn vs. Valori fara semn

.data

total dw 0FFFFh   ; sari daca total < 10 (cu semn)
.code

CMP total, 10

JL less10             ;sari daca total < 10

…

less10:
                         ;FFFFh = -1, codul va sari la less10 pt. ca –1 < 10.
                         ;sari daca total < 10 (fara semn)
CMP total, 10

JB less10             ; sare daca total < 10

….

less10:                ;Acest cod nu va efectua saltul la 

less10

 pentru ca valoarea
                         ;FFFFh luata fara semn este 65535 > 10.
 
Intrebare: Cum ştie programul daca sa considere FFFFh ca fiind –1 or 65,535?
Raspuns: Utilizatorul ii spune acest lucru prin tipul instructiunii de salt conditionat.

Utilizarea salturilor conditionate

  • Salturile conditionate sunt utilizate de obicei dupa o instructiune CMP.
  • Se pot utilizat salturi conditionate şi dupa o operatie aritmetica pentru ca şi acestea modifica bitii de flag in functie de rezultat.

Expresia de tip If implementata in limbaj de asamblare

Limbaj evoluat

In Assembler (tot in pseudo-cod!):

if (op1 = op2) then

 

<expresie1>

<expresie 2>

end if

cmp op1, op2

 

jne fals

< expresie 1>

< expresie 2>

fals:

<restul programului>

Exemplu aplicatie assembler in care este utilizata structura de control de tip IF

.data

op1 db 10

op2 db –12

op3 db ?

.code

mov al, op1             ;why?

cmp al, op2             ; op1 = op2?

jne eticheta             ; daca nu, sari

mov bl, op2             ;expresia 1

mov op3, bl             ;expresia 2

eticheta:

add al, op2

Expresia de tip IF-THEN-ELSE implementata in limbaj de asamblare

Limbaj evoluat

In Assembler (tot in pseudo-cod!):

if (temp > max) then

 

max = temp

else

max = max + 1

endif

cmp op1, op2

 

jle else

<statement1>

<statement2>

jmp done

else:

<statement3>

<statement4>

done:

Exemplu aplicatie assembler in care este utilizata structura de control de tip IF-THEN-ELSE

mov ax, temp

mov bx, max

cmp ax, bx             ;compara temp cu max

if:                    ;"if"

jle els                 ;sari daca temp <= max

mov max, ax             ;temp > max "then"

jmp done             ;salt neconditionat

else:

inc bx                 ; temp <= max "else"

mov max, bx

done:


Expresia de tip DO-WHILE implementata in limbaj de asamblare

Limbaj evoluat

In Assembler (tot in pseudo-cod!):

i=n;

 

do

{

<statement1>

<statement2>

i=i-1;

} while (i>=0)

mov cx,n

 

repeat:

<statement1>

<statement2>

loop repeat

 

Exemplu aplicatie assembler pentru determinarea sumei elementelor unui vector, ce implementeaza structura de control Do-While prin intermediul instructiunii Loop.

.model small

.286

.stack 100h

.data

vector db 1,2,3,4,5,6,7

n db 7                ;dimensiunea vectorului

suma db 0            ;suma elementelor

.code

mov AX,@data

mov DS,AX

xor SI,SI

xor CX,CX            ;ne asiguram ca CX are valoarea 0

mov CL,n            ;copiem in CL dimensiunea vectorului

repeat:              ;definim eticheta

mov AL,vector[SI]

add suma,AL
inc SI                ;marim valoarea din SI cu 1 pentru a trece la elementul urmator
loop repeat         ;salt la eticheta cat timp CX diferit de 0

mov AX,4c00h

int 21h

end


Expresia de tip WHILE-DO implementata in limbaj de asamblare

Limbaj evoluat

In Assembler (tot in pseudo-cod!):

i=n;

 

while (i>=0) do

{

<statement1>

<statement2>

i=i-1;

}

mov cx,n

 

repeat:

cmp op1,op2 ;verificare conditie

jle exit ;conditie iesire

<statement1>

<statement2>

loop repeat

exit:

Expresia de tip CASE implementata in limbaj de asamblare

Limbaj evoluat

In Assembler (tot in pseudo-cod!):

switch (value) {

 

case constant1:

<statement1>

break;

case constant2:

<statement2>

break;


default:

<statements>

cmp value,constant1

 

je case1

cmp value,constant2

je case2

jmp default

case1:

<statement1>

jmp final

case2:

<statement2>

Jmp final

default:

<statements>

final: