Inštrukcie dosadenia adresy


<= =>


I keď sme si už popísali, ako dosadiť hodnotu adresy do niektorého z adresových registrov, neboli možnosti ešte vyčerpané. Najjednoduchšie je použitie inštrukcie:

  • LEA adresový register, pamäť - do adresového registru dosaď adresu offsetu pamäti
  • Pamäť je v tomto prípade označená ako v inštrukcii MOV. Inštrukcia LEA BX, BYTE PTR [0xFF00] a MOV BX, 0xFF00 sú ekvivalentné. Pretože druhá inštrukcia je jednoduchšia, nemala by inštrukcia LEA význam. Preto ju častejšie použijeme pri hľadaní hodnoty kombinovanej adresy (LEA DI, 100[BX][SI] - sčíta registre s číslom 100 a dosadí výsledok do DI). Pre nás má význam i vo vkladanom assembleri. Zápis LEA BX, premenná je jednoduchší ako MOV BX, offset premenná (i keď inštrukcie vykonajú rovnakú prácu).
    unsigned char pole[10];
    void main() {
      asm {
        LEA BX, pole           // do registra BX dosaď adresu poľa
        MOV BYTE PTR [BX],10   // na prvé miesto v poli napíš 10
      }
    }

    Zatiaľ sme ovplyvňovali len registre s offsetom. Napriek tomu by sme boli schopní dosadiť i segment, bolo by nutné použiť najmenej tri inštrukcie (nezabudnite, že MOV nevie dosadiť hodnotu do segmentového registra priamo). Aby sme pochopili úspornejšiu inštrukciu, musíme si zopakovať pojem ukazovateľ.

    Ukazovateľ

    Je typ premennej, ktorý nesie celú adresu určitého miesta v pamäti. S pomocou týchto premenných môžeme potom dosadzovať hodnoty na miesta, kam ukazujú. Častejšie myslíme označením ukazovateľ práve tieto premenné.
    #include <stdio.h>
    unsigned char cislo;       // vyčleň v pamäti slabiku, označ ju cislo
    unsigned char *ukazovatel; // vyčleň v pamäti štyri slabiky, ktoré ponesú adresu
                               // na premennú typu byte, označ ich ukazovateľ
    main() {
      ukazovatel = &cislo;     // ukazovateľu priraď adresu premennej cislo
      *ukazovatel =10;         // na miesto kam smeruje ukazovateľ zapíš 10
      printf(”Hodnota premennej cislo:%d=%d”,cislo,*ukazovatel); // vypíš
    }

    Okrem ukazovateľov na daný typ existujú i ukazovatele všeobecné (pointer na void). Tieto typy sú pre nás dôležité. Štyri slabiky, ktoré sú pre premennú tohoto typu vyčlenené, nesú totiž segment i offset adresy, kam ukazovateľ smeruje. V assembleri existujú dve inštrukcie, ktoré sú schopné adresy uložené v ukazovateli dosadiť do registrov segmentu i offsetu:

    #include <stdio.h>
    unsigned char premenna;          // v pamäti vyčleň slabiku s označením premenna
    void *ukazovatel;                // v pamäti vyčleň štyri slabiky pre ukazovateľ
    
    main() {
      ukazovatel = &premenna;        // nasmeruj ukazovateľ na premennú
      asm {
        LES BX, ukazovatel           // nastav ES:BX na adresu premennej
        SEGES MOV BYTE PTR [BX],10   // zapíš na túto adresu
      }
      printf(“%d”,premenna);         // vypíš obsah premennej
    }
    



    <= =>