Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Question about stack...

1 view
Skip to first unread message

wolf3y3

unread,
Nov 21, 2009, 4:43:09 PM11/21/09
to

So I'm reserving room on the stack for a local variable,
I'm in 16-bit assembly and I decide to reserve room for a 16-bit word,
so I subtract 2 from sp.
SUB SP, 2
MOV BP, SP
MOV word [BP], myvalue
In this case it wasn't overwritten.
When I didn't adjust the value of SP and did:
MOV BP, SP
MOV WORD [BP-2], myvalue
I didn't even push anything on the stack and my value was destroyed.
Is this because of external interrupts, which need to use the current
stack periodically?
Thanks in advance.

Alexei A. Frounze

unread,
Nov 21, 2009, 10:07:50 PM11/21/09
to

Yes, it's possible. Also if your code did any PUSH or CALL after this,
it destroyed the value too.

> Thanks in advance.

Alex

Robert Redelmeier

unread,
Nov 21, 2009, 10:08:08 PM11/21/09
to

wolf3y3 <wol...@munged.microcosmotalk.com> wrote in part:

> So I'm reserving room on the stack for a local variable,
> I'm in 16-bit assembly and I decide to reserve room for a
> 16-bit word, so I subtract 2 from sp.

Fine so far

> SUB SP, 2
> MOV BP, SP

These instructions are normally in the other order,
BP is set to ToS at procedure entry and procedure
params are at BP-x , locals at BP+y , and ret addr
at BP+0 . Dealloc of locals is a simple `mov sp, bp`


> MOV word [BP], myvalue
> In this case it wasn't overwritten.
> When I didn't adjust the value of SP and did:
> MOV BP, SP
> MOV WORD [BP-2], myvalue
> I didn't even push anything on the stack and my value was
> destroyed. Is this because of external interrupts, which need
> to use the current stack periodically? Thanks in advance.

Under MS-DOS, yes. It handles ethernet, timer ticks, and maybe
even kbd debouncing. But uses the user stack, so user stack has
to be in safe space (when interrupts not cleared). pmode OSes
(OS/2, Linux, *BSD, MS-WinNT+) switch to a kernel stack.


-- Robert

Dick Wesseling

unread,
Nov 22, 2009, 2:45:35 AM11/22/09
to

In article <4b08ab18$0$4856$9a6e...@unlimited.newshosting.com>,

I don't know how OS/2 and MS-* handle this, but the other OSes
use the user stack for signal handlers unless the application
sets up a signal stack.
The amd64 ABI provides a 128 byte "red zone" below SP that will
not be clobbered by signal handlers. This makes it possible to
address local variables using SP-offset without explicitly allocating
the variables.

pe...@nospam.demon.co.uk

unread,
Nov 22, 2009, 2:46:24 AM11/22/09
to

In article <4b08ab18$0$4856$9a6e...@unlimited.newshosting.com>
red...@ev1.net.invalid "Robert Redelmeier" writes:

>
> wolf3y3 <wol...@munged.microcosmotalk.com> wrote in part:
> > So I'm reserving room on the stack for a local variable,
> > I'm in 16-bit assembly and I decide to reserve room for a
> > 16-bit word, so I subtract 2 from sp.
>
> Fine so far
>
> > SUB SP, 2
> > MOV BP, SP
>
> These instructions are normally in the other order,
> BP is set to ToS at procedure entry and procedure
> params are at BP-x , locals at BP+y , and ret addr
> at BP+0 . Dealloc of locals is a simple `mov sp, bp`

Or the other way round: params at BP+x, locals at BP-x?

The "usual" sequence of instructions for a function are

push bp ; do save!
mov bp, sp ; set new stack frame
sub sp, num ; num = size of locals
...
body of function
...
mov sp, bp ; deallocate locals
pop bp ; restore
ret ;

> > MOV word [BP], myvalue
> > In this case it wasn't overwritten.
> > When I didn't adjust the value of SP and did:
> > MOV BP, SP
> > MOV WORD [BP-2], myvalue
> > I didn't even push anything on the stack and my value was
> > destroyed. Is this because of external interrupts, which need
> > to use the current stack periodically? Thanks in advance.
>
> Under MS-DOS, yes. It handles ethernet, timer ticks, and maybe
> even kbd debouncing. But uses the user stack, so user stack has
> to be in safe space (when interrupts not cleared). pmode OSes
> (OS/2, Linux, *BSD, MS-WinNT+) switch to a kernel stack.

Having said that though (and provided the stack is large enough)
this is quite safe under MSDOS provided that SP is always
pointing to a "safe" place. After you have SUB SP,x any external
interrupts etc. will use this new SP value so use the stack below
your local vars.

Incidentally, if all you need is space for a 16-bit value you
could simply PUSH something. This will implicitly decrease SP by
two:

push bp ;
mov bp, sp ; set new stack frame
push ax ; or anything, even your local var if you
; know its value
...
You can no refer to your var through [BP-2]
...
mov sp, bp ; deallocate locals
pop bp ; restore
ret ;

And if you want to return your local var in e.g. AX from the
function, replace the MOV SP,BP with POP AX.

Pete
--
"We have not inherited the earth from our ancestors,
we have borrowed it from our descendants."

Robert Redelmeier

unread,
Nov 22, 2009, 10:54:19 AM11/22/09
to

pe...@nospam.demon.co.uk wrote in part:

> Or the other way round: params at BP+x, locals at BP-x?

Doh! You are correct. Grow-down makes for confusion.

-- Robert

Robert Redelmeier

unread,
Nov 22, 2009, 10:56:01 AM11/22/09
to

Dick Wesseling <fr...@munged.microcosmotalk.com> wrote in part:

>> even kbd debouncing. But uses the user stack, so user stack has
>> to be in safe space (when interrupts not cleared). pmode OSes
>> (OS/2, Linux, *BSD, MS-WinNT+) switch to a kernel stack.
>
> I don't know how OS/2 and MS-* handle this, but the other
> OSes use the user stack for signal handlers unless the
> application sets up a signal stack.

I don't think so -- I just tested under Linux, and it does
not require any valid ESP . xor to set it to the zeropage.
Then loop a while. Had there been any r/w on ESP, it would
have segfaulted.

> The amd64 ABI provides a 128 byte "red zone" below SP that
> will not be clobbered by signal handlers. This makes it
> possible to address local variables using SP-offset without
> explicitly allocating the variables.

This can be done on any good pmode OS raw. However, it is
somewhat undefined. I have no idea what the various libc do,
especially with their "signals" (ASM talks interrupts).


-- Robert

Dick Wesseling

unread,
Nov 22, 2009, 4:33:04 PM11/22/09
to

In article <4b095f11$0$4892$9a6e...@unlimited.newshosting.com>,

Robert Redelmeier <red...@ev1.net.invalid> writes:
>
> Dick Wesseling <fr...@munged.microcosmotalk.com> wrote in part:
>>> even kbd debouncing. But uses the user stack, so user stack has
>>> to be in safe space (when interrupts not cleared). pmode OSes
>>> (OS/2, Linux, *BSD, MS-WinNT+) switch to a kernel stack.
>>
>> I don't know how OS/2 and MS-* handle this, but the other
>> OSes use the user stack for signal handlers unless the
>> application sets up a signal stack.
>
> I don't think so -- I just tested under Linux, and it does
> not require any valid ESP . xor to set it to the zeropage.
> Then loop a while. Had there been any r/w on ESP, it would
> have segfaulted.
>

But did you get a signal while looping with invalid ESP?

Try this, assuming that testloop() takes at least a second
on your CPU the signal handle should segfault:


#include <signal.h>
#include <stdio.h>

void testloop() {
asm("movl %esp,%eax\n"
"xorl %esp,%esp\n" /* ESP = NULL */
"xorl %edx,%edx\n"
"1: decl %edx\n" /* this should take >1s */
"1: jne 1b\n"
"1: decl %edx\n"
"1: jne 1b\n"
"movl %eax,%esp\n" /* restore ESP */
);

}

void myhandler(int n) {
}

int main(int argc, char **arv) {
signal(SIGALRM, myhandler);
alarm(1);
testloop();
printf("worked\n");
return 0;
}

Robert Redelmeier

unread,
Nov 23, 2009, 4:26:42 AM11/23/09
to

Dick Wesseling <fr...@munged.microcosmotalk.com> wrote in part:
> In article <4b095f11$0$4892$9a6e...@unlimited.newshosting.com>,
> Robert Redelmeier <red...@ev1.net.invalid> writes:
>>
>> Dick Wesseling <fr...@munged.microcosmotalk.com> wrote in part:
>>>> even kbd debouncing. But uses the user stack, so user stack has
>>>> to be in safe space (when interrupts not cleared). pmode OSes
>>>> (OS/2, Linux, *BSD, MS-WinNT+) switch to a kernel stack.
>>>
>>> I don't know how OS/2 and MS-* handle this, but the other
>>> OSes use the user stack for signal handlers unless the
>>> application sets up a signal stack.
>>
>> I don't think so -- I just tested under Linux, and it does
>> not require any valid ESP . xor to set it to the zeropage.
>> Then loop a while. Had there been any r/w on ESP, it would
>> have segfaulted.
>>
>
> But did you get a signal while looping with invalid ESP?

I'm not running a tickless Linux system, so I'm sure the system
handled at least 500 timer ticks, plus ethernet. All kernel
interrupts. As for C signals, I have no idea how libc handles them.


-- Robert

Bjarni Juliusson

unread,
Nov 26, 2009, 10:16:36 PM11/26/09
to

>>>>> even kbd debouncing. But uses the user stack, so user stack has
>>>>> to be in safe space (when interrupts not cleared). pmode OSes
>>>>> (OS/2, Linux, *BSD, MS-WinNT+) switch to a kernel stack.
>>>>
>>>> I don't know how OS/2 and MS-* handle this, but the other
>>>> OSes use the user stack for signal handlers unless the
>>>> application sets up a signal stack.
>>>
>>> I don't think so -- I just tested under Linux, and it does
>>> not require any valid ESP . xor to set it to the zeropage.
>>> Then loop a while. Had there been any r/w on ESP, it would
>>> have segfaulted.
>>>
>>
>> But did you get a signal while looping with invalid ESP?
>
> I'm not running a tickless Linux system, so I'm sure the system
> handled at least 500 timer ticks, plus ethernet. All kernel
> interrupts. As for C signals, I have no idea how libc handles them.

But we are not talking about libc or the kernel. Signals are part of the
definition of user processes in Unix. Thus, while it is true that "pmode
OSes switch to a kernel stack" to handle interrupts, Unix signals are an
example of other asynchronous events that may use the user stack under
many operating systems.

The moral of all this is that a program should never use space below the
current stack pointer, as this is to be considered unallocated and may
be asynchronously clobbered by things like signals in most cases, and
also by hardware interrupts in the case of MSDOS and other simple
operating systems.


Bjarni
--

INFORMATION WANTS TO BE FREE

0 new messages