Navigacija
Lista poslednjih: 16, 32, 64, 128 poruka.

unsigned int far

[es] :: C/C++ programiranje :: unsigned int far

[ Pregleda: 3350 | Odgovora: 4 ] > FB > Twit

Postavi temu Odgovori

Autor

Pretraga teme: Traži
Markiranje Štampanje RSS

slavkot

Član broj: 18657
Poruke: 166
*.teol.net.



Profil

icon unsigned int far24.10.2004. u 22:30 - pre 237 meseci
Pozdrav, radi se o programu koji provjerava adresu portova

#include <stdio.h>
#include <dos.h>
void main(void)
{
unsigned int far *ptraddr; /* Pointer to location of Port Addresses */
unsigned int address; /* Address of Port */
int a;
ptraddr=(unsigned int far *)0x00000400;
for (a = 0; a < 4; a++)
{
address = *ptraddr;
if (address == 0)
printf("No port found for COM%d \n",a+1);
else
printf("Address assigned to COM%d is %Xh\n",a+1,address);
*ptraddr++;
}
}

ali ovaj unsigned int far *ptraddr; neće da proguta, šta je far, šta treba promjeniti, kako da ga se rješim ?
 
Odgovor na temu

Dragi Tata
Malo ispod Kanade

Član broj: 1958
Poruke: 3906
*.bos.east.verizon.net.



+6 Profil

icon Re: unsigned int far24.10.2004. u 22:53 - pre 237 meseci
Hehehe, stara dobra DOS vremena.

Nađi neki kompajler za DOS kao što je Turbo C i budi siguran da koristiš Windows 9x/ME, a ne NT/2000/XP/2003
 
Odgovor na temu

slavkot

Član broj: 18657
Poruke: 166
*.teol.net.



Profil

icon Re: unsigned int far24.10.2004. u 23:08 - pre 237 meseci
Koristim windows xp i nije mi u cilju da program proradi, jer znam da su adrese portova
COM 1 3F8
COM 2 2F8
COM 3 3E8
COM 4 2E8

, nego me ovaj "far" zbunio, jel ima neka zamjena za njega ?
Uostalom nije bitno, samo ovaj primjer sadrži taj "far".
 
Odgovor na temu

zvrba
The Lord of Chaos

Član broj: 31716
Poruke: 105
*.fina.hr.



Profil

icon Re: unsigned int far25.10.2004. u 08:10 - pre 237 meseci
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

 
Odgovor na temu

slavkot

Član broj: 18657
Poruke: 166
*.teol.net.



Profil

icon Re: unsigned int far25.10.2004. u 14:27 - pre 237 meseci
Hvala zvrba na objašnjenju
 
Odgovor na temu

[es] :: C/C++ programiranje :: unsigned int far

[ Pregleda: 3350 | Odgovora: 4 ] > FB > Twit

Postavi temu Odgovori

Navigacija
Lista poslednjih: 16, 32, 64, 128 poruka.