//(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!
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.
I use VisualC++6, and there all local variables are in CS, and the address is CSI 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 CSI 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:
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>:
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 "a".
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.
This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
By continuing to use this site, you are consenting to our use of cookies.