Učebnice Assembleru 86

Instrukce dosazení adresy

I když jsme si již popsali, jak dosadit hodnotu adresy do některého z adresových registrů, nebyly možnosti ještě vyčerpány. Nejjednodušší je použití instrukce:

  • LEA adresový registr, paměť - do adresového registru dosaď adresu offsetu paměti

Paměť je v tomto případě označena jako v instrukci MOV. Instrukce LEA BX, BYTE PTR [$FF00] a MOV BX, $FF00 jsou ekvivalentní. Protože druhá instrukce je jednodušší, neměla by instrukce LEA význam. Proto ji častěji použijeme při hledání hodnoty kombinované adresy (LEA DI, 100[BX][SI] - sečte registry s číslem 100 a dosadí výsledek do DI). Pro nás má význam i ve vkládaném assembleru. Zápis LEA BX, proměnná je jednodušší něž MOV BX, offset proměnná (i když instrukce vykonají stejnou práci).

Příklad:

var pole: array [0..9] of byte;
begin
 asm
  LEA BX, pole         {do registru BX dosaď adresu pole}
  MOV BYTE PTR [BX],10 {na první místo v poli napiš 10}
 end;
end.

Zatím jsme ovlivňovali jen registry s offsetem. Přestože bychom byli schopni dosadit i segment, bylo by nutné použít nejméně tři instrukce (nezapomeňte, že MOV neumí dosadit hodnotu do segmentového registru přímo). Abychom pochopili úspornější instrukci, musíme si zopakovat pojem ukazatel.

Ukazatel

Je typ proměnné, který nese celou adresu určitého místa v paměti. S pomocí těchto proměnných můžeme potom dosazovat hodnoty na místa, kam ukazují. Častěji myslíme označením ukazatel právě tyto proměnné.
Příklad:

var cislo:byte;    {vyčleň v paměti slabiku, označ jí číslo}
 ukazatel:^byte;   {vyčleň v paměti čtyři slabiky, které ponesou}
                   {adresu na proměnnou typu byte, označ je ukazatel}
begin
 ukazatel:=@cislo; {ukazateli přiřaď adresu proměnné číslo}
 ukazatel^:=10;    {na místo kam směřuje ukazatel zapiš 10}
 writeln ('Hodnota proměnné číslo:',cislo,'=',ukazatel^); {vypiš}
end.

Kromě ukazatelů na daný typ existují i ukazatele obecně (typ pointer). Tyto typy jsou pro nás důležité. Čtyři slabiky, které jsou pro proměnnou tohoto typu vyčleněny, nesou totiž segment i offset adresy, kam ukazatel směřuje. V assembleru existují dvě instrukce, které jsou schopny adresy uložené v ukazateli dosadit do registrů segmentu i offsetu:

  • LES registr, ukazatel - do ES dosaď segment a registru offset adresy směru ukazatele
  • LDS registr, ukazatel - do DS dosaď segment a registru offset adresy směru ukazatele

Příklad:

var promenna: byte;   {v paměti vyčleň slabiku s označením proměnná}
    ukazatel: poiter; {v paměti vyčleň čtyři slabiky pro ukazatel}
begin
 ukazatel:=@promenna; {nasměruj ukazatele na proměnnou}
 asm
  LES BX, ukazatel           {nastav ES:BX na adresu proměnné}
  SEGES MOV BYTE PTR [BX],10 {zapiš na tuto adresu}
 end;
writeln (promenna);  {vypiš obsah proměnné}
end.

Směr