That's not what I'm talking about!
Accessing local variables is fine because the x86 implicitly uses SS when accessing memory via EBP or ESP.
Look at this code which forms two pointers to two strings and tries to use them.
Code: Select all
char global_string[] = "This string is global";
int main(void)
{
24: e8 00 00 00 00 call 29 <_main+0xd>
/cygdrive/h/temp.c:7
char stack_string[] = "This string is on the stack";
29: 8d 45 e0 lea 0xffffffe0(%ebp),%eax
2c: 8d 7d e0 lea 0xffffffe0(%ebp),%edi
2f: be 00 00 00 00 mov $0x0,%esi
34: fc cld
35: b9 07 00 00 00 mov $0x7,%ecx
3a: f3 a5 repz movsl %ds:(%esi),%es:(%edi)
Here a string is put onto the stack.
Code: Select all
/cygdrive/h/temp.c:9
char *p1, *p2;
p1 = global_string;
3c: c7 45 dc 00 00 00 00 movl $0x0,0xffffffdc(%ebp)
/cygdrive/h/temp.c:10
p2 = stack_string;
43: 8d 45 e0 lea 0xffffffe0(%ebp),%eax
46: 89 45 d8 mov %eax,0xffffffd8(%ebp)
Here pointers are formed to each string. Note that global_string is referred to by an absolute address (it is zero here because this code has not been linked yet). stack_string is referred to with ebp-relative addressing. p1 is relative to DS, and p2 is relative to SS. So far so good.
Code: Select all
/cygdrive/h/temp.c:11
puts(p1);
49: 83 c4 f4 add $0xfffffff4,%esp
4c: 8b 45 dc mov 0xffffffdc(%ebp),%eax
4f: 50 push %eax
50: e8 00 00 00 00 call 55 <_main+0x39>
55: 83 c4 10 add $0x10,%esp
/cygdrive/h/temp.c:12
puts(p2);
58: 83 c4 f4 add $0xfffffff4,%esp
5b: 8b 45 d8 mov 0xffffffd8(%ebp),%eax
5e: 50 push %eax
5f: e8 00 00 00 00 call 64 <_main+0x48>
64: 83 c4 10 add $0x10,%esp
Here puts is called twice, with the pointers to the strings we just got. But each call is made in exactly the same way: the fact that stack_string is on the stack is ignored. Inside puts there will be instructions which fetch each character of the string without a segment override, so the characters will be obtained from the data segment. puts will get the wrong segment for stack string unless either:
(1) you pass it a far pointer to the string (which is impossible with gcc, which I used here)
(2) the base addresses of SS and DS are identical
gcc assumes (2) on the bx86.