Hm. Ima zamjena za 'far' (__far, valjda :)), ali nece raditi ono sto ocekujes.
Naime, u DOS-u imas memory model programa. far znaci da radis s pointerom od 2 dijela: segment i offset. Ako ostavis default, onda ovisi o memory modelu, a ako stavis near, onda radis samo sa offsetom.
U DOS-u je bila ovakva kalkulacija: fizicka adresa = segment * 16 + offset (segment se nalazi u nekom od segmentnih registara). Pod windozama je puno kompliciranije - sadrzaj segmentnog registra je u biti samo offset u tablicu deskriptora (lokalnu ili globalnu) pa se iz nje racuna linearna adresa - detalje sam objasnio u
http://www.elitesecurity.org/tema/38600
'far' pointere treba izbjegavati jer nisu u skladu s memorijskim modelom koji ocekuje definicija C jezika. Npr. moguca je anomalija da dva RAZLICITA pointera pokazuju na ISTU memorijsku lokaciju!
Npr. pod DOSom, pointeri (prvi broj je segment, drugi je offset; to je tradicionalna notacija) 0x02:0x65 i 0x08:0x05 pokazuju na ISTU memorijsku lokaciju jer je 0x02 * 16 + 0x65 = 0x20 + 0x65 = 0x85 , 0x08 * 16 + 0x05 = 0x80 + 0x05 = 0x85. U protected modu nema jednostavne racunice; treba se referencirati na tablicu deskriptora.
Buduci da takvi pointeri nisu 'linearni', problem nastaje i kod njihove usporedbe. far pointeri su u biti neusporedivi i ne sjecam se sto se desi ako ih pokusas usporedjivati sa < i > (sto je dozvoljeno u C-u). Mozda prijavi gresku, mozda dobijes besmislen rezultat.
Zato su stari kompajleri definirali i 'huge' pointere koji su far pointeri u normaliziranom obliku i nad kojima je uvijek ispravno radila bilo kakva usporedba i pointer aritmetika. Medjutim, bili su SPORIJI od 'far' pointera jer je kompajler uvijek generirao kod da far pointeri budu normalizirani. Normalizacija je stavljala restrikcije na segment i offset, ali se ne sjecam tocno kakve. Dva nacina mi padaju na pamet:
1. restrikcija offseta na range 0-15
2. restrikcija segmenta na vrijednosti, 0x0, 0x1000, 0x2000, itd. (dakle, rangevi od 64k), te pun range offseta 0-65535
Npr. u 16-bitnom kodu, ako imas far pointer i offset koji na lokaciji a i cjelobrojni offset koji mu zelis dodati na lokaciji b (svaki far pointer zauzima 4 bajta, od toga su prva dva bajta offset, druga dva segment):
kod za 1. nacin:
Code:
mov ax, [a] ; offset pointera
add ax, [b] ; dodaj cjelobrojni offset
mov bl, al ; normaliziraj offset na 0-15
and bl, 15
mov [a], bl ; spremi offset nakon zbrajanja
shr ax, 4 ; preljev koji treba dodati
add [a+2], ax ; segmentnom dijelu pointera
kod za 2. nacin:
Code:
mov ax, [b] ; cjelobrojni offset
add [a], ax ; dodaj ga offset dijelu pointera
mov ax, 0 ; ne smije a/l instrukcija jer mijenjaju carry
rcr ax, 1 ; stavi carry flag u 15. bit (ax je ili 0 ili 0x1000, ovisno o carry flagu)
add [a+2], ax ; dodaj preljev u segmentni dio pointera
Oba nacina su evidentno sporija od jedne potrebne instrukcije ako se radi sa near pointerima (sto je uvijek slucaj u 32-bitnom modu):
Code:
mov eax, [b] ; cjelobrojni offset
add [a], eax ; dodaj ga pointeru