W obu przypadkach <adres> jest jedynie offsetem, który dodajemy do adresu początku segmentu. Nie wiem czy dobrze pamiętam, ale gdy nie podamy jawnie segmentu wtedy użyty jest właśnie ds, więc oba przypadki dają ten sam adres.
W przypadku większości instrukcji domyślnym segmentem jest ds
.
W trybie rzeczywistym (real mode) adres wynikowy jest liczony jako segment*16 + offset
.
W trybie chronionym (protected mode) rejestr segmentowy jest rodzajem wskaźnika (selektorem) do tablicy deskryptorów. Jest to tablica tworzona przez system operacyjny z rekordami zawierającymi (między innymi) adres bazowy i limit (rozmiar) segmentu.
Adres jest więc liczony jako tablica_deskryptorów[segment].adres_bazowy + offset
Jeśli włączone jest stronicowanie (paging) tak wyliczony adres podlega dalszemu "przekłamaniu" zgodnie z tablicami stronicowania: pamięć podzielona jest na fragmenty zwane stronami (standardowo 4 kB, ale są tryby ze stronami 2 MB, 4 MB i 1 GB). kolejność stron w fizycznej pamięci może być dowolnie przemieszana. w ten sposób program może widzieć ciągły obszar pamięci, który fizycznie jest podzielony na kawałki.
W praktyce 32-bitowe systemy operacyjne ustawiają cs, ds, es i ss na adres bazowy 0 i limit max (czyli 4 GB) w efekcie segmentacja tak jakby nie istniała i można o niej zapomnieć. system operuje tylko stronicowaniem, które jest dla programów przezroczyste.