Yes, but to you and those who mentioned something similar: keep in mind what I said above: what you describe is memory protection. What I suggested was for code instrumentation (with stacks in mind here, but I do have a knack for code instrumentation anyway.) Those are two different things.
Agreed; that is also why I qualified it with
"If you expand the idea".
The security aspect can obviously used for instrumentation (at a suitable granularity), by simply having the out-of-bounds access interrupt expand the region. It is probably not useful to make it byte-granular, but it does cover
all accesses to that segment.
you can define a memory area for a stack and protect it, but there's little way you can prevent some program to write outside of the stack area, when it means to write inside of it, if this 'outside' location is itself another memory area that is allowed to be written to.
That is precisely why the segmented memory model so intrigues me: because the "segment register" acts as the key to the address space, it does affect all accesses. For a stack, it means that an OS on x86-64 could trivially have separate segments (and segment descriptors) for stack data, and initially only allocate a single page; and whenever a page fault in that segment occurs, the OS kernel could expand the mapping up to whatever process-specific limits. There would be
some overhead/slowdown, but I
guess it would be neglible compared to the issues with fixed-size per-thread stacks in e.g. Linux. (Even virtual address space without backing pages, costs resources.)
What I don't know how to implement, is any sort of automatic shrinking of such segments; or even how to instrument it. Yes, you can track accesses, but only the process itself knows when the data in that segment is no longer needed; perhaps it knows that it will never need more than
N bytes of stack, and uses a region beyond that as an extra scratchpad or something.
It is also the reason why I find named address spaces (on any hardware that can use them, not just on hardware that has to use them like Harvard architecture AVRs without an unified address space) so darned intriguing and useful in embedded/freestanding C and C++. It just makes all the complexity and overhead *vanish*.
(I've experimented a bit about vectors or indirect addressing modes including address space identifiers within the
value, or address of the pointer, some time ago, and how to expose that to a C or C++ like systems programming language. I admitted defeat there; it is technically possible, but the complexity needed and overhead spent is way more than what benefits I could squeeze out of it. "Segment register overrides", or instruction prefixes/modifiers that specify the nonstandard address space the instruction operates on, with a couple of CSRs defining those address spaces, is just delightfully simple and effective in comparison. Granted, I have NOT implemented anything on an FPGA yet, so my opinion on this is subject to change once I do.)