Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations IamaSherpa on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Segment of pointer in Turbo C

Status
Not open for further replies.

Jenda

Programmer
Feb 27, 2001
14
CZ
Hello

Is any way to get the segment address of pointer?
My program language is Turbo C.
example:

char x;
Word off,seg;

off = &x;
seg = ???????????

Thank you Jenda
 
It is better to use defined in DOS.H
macros FP_SEG(void far *p) and FP_OFF(void far *p):

seg=FP_SEG(&x)
off=FP_OFF(&x)


 
I tried both answers but look :

Byte a;
Word off,seg;

//(1) - using assembler
asm les di,[a]
asm mov ax,es
asm mov [seg],ax
asm mov ax,di
asm mov [off],ax

//(2) - using DOS.H
seg = FP_SEG(&a);
off = FP_OFF(&a);

printf("address of a = %p\n",a);
printf("offset of a = %u\n:",off);
printf("segment of a = %u\n:",seg);

And now:
--------
when I ran this program with section (1) or (2) (it doesn't mean),printed offset address was the same (after conversion from dec to hex), but segment address wasn't!
Please explain this!

Thank's Jenda
 
If pointer points to a local variable, the segment will be CS, not DS or ES. John Fill
ivfmd@mail.md
 
No. a poiter of a local variable is in DS segment, not CS. Maybe it's not
always the case but sure in Turbo C it is.
I wonder how Jenda's codes works but at least it runs wrong in Turbo 2.0:

1. asm les di,[a]
This line can't pass the assembler.
2. printf("address of a = %p\n",a);
This line doesn't give the address of a, but the value in pointer format.
&a is correct.

Johnfil's code is all right for the segment value.

Jennings
 
I use VisualC++6, and there all local variables are in CS, and the address is CS:DI or CS:SI (I saw it in debugger). If is a parameter variable, the segment is SS. Usualy I develop Windows 32bit programs what use unique ESI,EDI wich do not require segmentation. About TurboC2.0, I do not know. But in assembler programs, also use CS:DI and CS:SI to make local variables. John Fill
ivfmd@mail.md
 
So things are quite different in Turbo C. There are different models in
Turbo C. In tiny/small model all variables are in one segment and SS has
the same value with DS. In large data models the variables may locate in
different segments so they may have different DS, and the variables in SS
may have a different segment value. No variables in CS for all models.

1. MOV AX,DS is an alternative method to get the segment value,
it should be correct at least in tiny/small model of Turbo C:

unsigned getDS()
{
asm mov ax,ds
}

main()
{
char a;
printf("Address of a: %4.4X:%4.4X\n", getDS(), &a);
}

you can also use %p to format &a in the printf statement here for tiny and
small models. For large data models, %p gives both the segment and
offset value of a variable, so getDS() is useless.

2. Professionals would say "char a" is not addressed in DS, but in SS.
Yes. strictly, in Turbo C, global variables and local static variables
are in the DATA segment (using DS), others in STACK(SS). For example,

int a, b=0;
foo(int c)
{ static int x=0;
int y=1;
char z[8]="abcdefg";
...
}

a,b,x are in the DATA segment, c, y, z are in the STACK (allocated at
runtime). You will find &c,&y and z have offsets near 0xFFFF, while
&a, &b and &x are rather lower.
But SS has the same value as DS in tiny/small model in Turbo C. So all
the variables are in the same segment in tiny/small model and the above
code should run well.

3. As MisterNobody recommended, FP_SEG(&a) and FP_OFF(&a) always give
the right segment and offset of variable "a" for all models. It's much safer
to use these macros defined in <dos.h>:

#define FP_OFF(fp) ((unsigned)(fp))
#define FP_SEG(fp) ((unsigned)((unsigned long)(fp)>>16))

At the first glance of the macro definitions in dos.h, it seems NG for
tiny/small model, because &a is not a far pointer. However, in the
executable it really gives MOV DX,DS or MOV DX,SS if you assign &a as
the argument; otherwise, if you assign a as the argument, it gives CWD.
i still wonder how the compiler does the macros so clever.

4. les di,[a] puts the word value of a+0 in DI and the word value of
a+2 to ES. so you can get neither the offset nor the segment of the
variable &quot;a&quot;.

Example:

int x=0x1234,y=0x5678;
asm les di,[x]

You will get es=0x5678, di=0x1234. Neither the segment nor the offset
of x, but the two successive word values stored at x.

i think, however, it's not very necessary to get the segment value of a
variable. i cannot imagine even what the use of it.

Jennings
 
I tried all, what Jennigs wrote :
getDS didn't go - I compared value getDS with _DS and they wasn't the same. But it doesn't depends.

The best for extract segment and offset from variable is really FP_SEG and FP_OFF.
This goes in 100% in all memory models;

I agree with Jennigs it's not necessary to get segment of variables, but my work was to analyze completed program in C and there I found this problem.

Many thanks to all for your supplies!!
Jenda.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top