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

Real mode stack underflow - any exceptions?

63 views
Skip to first unread message

James Harris

unread,
Apr 8, 2012, 5:01:12 PM4/8/12
to
I am having trouble interpreting an Intel instruction definition. Can
you make sense of it? The question is if in real mode I pop the stack
to a register what exceptions are possible? According to

http://pdos.csail.mit.edu/6.828/2007/readings/i386/POP.htm

in real mode pop can experience the following exception.

Interrupt 13 if any part of the operand would lie outside of the
effective address space from 0 to 0FFFFH

What does it mean by "the operand"? Is it talking solely about pop to
memory or could an exception be generated in real mode for pop to a
register perhaps because the stack underflows?

James

ArarghMai...@nospicedham.not.at.arargh.com

unread,
Apr 8, 2012, 8:13:16 PM4/8/12
to
push and pop ALWAYS reference memory, at least once. Twice if you
push or pop to a memory location. After all, where do you think the
stack lives?

"the operand" is that part of the stack that is about to be
referenced by the pop instruction.

IIRC, in real mode, if SP=0FFFEh then pop gets the exception.



>
>James
--
ArarghMail204 at [drop the 'http://www.' from ->] http://www.arargh.com
BCET Basic Compiler Page: http://www.arargh.com/basic/index.html

To reply by email, remove the extra stuff from the reply address.

Rod Pemberton

unread,
Apr 8, 2012, 8:49:10 PM4/8/12
to
"James Harris" <james.h...@nospicedham.gmail.com> wrote in message
news:b710ae32-30af-42d8...@a5g2000vbl.googlegroups.com...
"... pop to memory ..." ?
Perhaps, pop *from* memory ...


The "operand" is the two bytes of data stored at the address being
popped for real mode.

Yes, with the pop instruction in RM, Int 13 is for stack underflows (top of
RM segment address range near offset 0FFFFh). It's not just for pop's with
specified memory locations. It's for all pop's in RM.

E.g., your initial stack SP is too close to 0FFFFh and SP was not aligned to
an even address: 0FFFEh, 0FFFCh, etc. If you have a pop which is at offset
0FFFFh, the first byte will be stored at 0FFFFh and the other could be in
one of two places due to address wrapping or lack of. Where the second byte
was stored depends on how the 2nd byte was stored, if it was stored, e.g.,
in RM as bytes with wrap (segment boundary) so the 2nd byte would be offset
0h, in PM without wrap (A20 boundary) prior to returning to RM so the 2nd
byte would be 010000h - effectively one byte into next segment, etc. The
location for the 2nd byte may be at offset 0h in the current segment or
effectively the first byte of the next segment 010000h. When the pop
attempts to read the 2nd byte, i.e., effectively first byte of the next
segment 010000h, the 2nd byte is outside the address space of the current
segment since it's beyond 0FFFFh and it therefore should trigger Int 0x0D.


Rod Pemberton



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

unread,
Apr 9, 2012, 1:58:33 AM4/9/12
to
In article <jltbm7$prg$1...@speranza.aioe.org>
That's just what Ralf Brown has to say (and it would appear that it's
not restricted to push/pop instructions):

---- quote -----------------------------------------------------------
INT 0D C - CPU-generated (80286+) - GENERAL PROTECTION VIOLATION
Desc: the CPU generates this interrupt when it detects a protection violation
which does not fit under any other category having a separate
interrupt
Notes: called in real mode when
an instruction accesses a memory operand extending beyond offset
FFFFh (i.e. WORD at FFFFh or DWORD at FFFDh or higher) in segment
CS, DS, ES, FG, or GS
a PUSH MEM or POP MEM instruction contains an invalid bit encoding
in the second byte
an instruction exceeds the maximum length allowed (10 bytes for
80286, 15 bytes for 80386/80486)
an instruction wraps from offset FFFFh to offset 0000h
called in protected mode on protection violations not covered by INT 06
through INT 0C, including
segment limit violations
write to read-only segments
accesses using null DS or ES selectors
accesses to segments with privilege greater than CPL
wrong descriptor type
called on 80486 protected-mode floating-point protection fault
---- end quote -------------------------------------------------------

Pete

--
Believe those who are seeking the truth.
Doubt those who find it. - André Gide

wolfgang kern

unread,
Apr 9, 2012, 6:19:40 AM4/9/12
to

James Harris wrote:

>I am having trouble interpreting an Intel instruction definition. Can
> you make sense of it? The question is if in real mode I pop the stack
> to a register what exceptions are possible? According to

> http://pdos.csail.mit.edu/6.828/2007/readings/i386/POP.htm

I assume true real mode rather than VM86,
"POP reg16"
can raise exception 0x0c if SP was 0xFFFF (stack bound crossing),
and it also should if SP was 0xFFFE and become 0 after the POP,
but I remember early 286 which allowed this aligned stack-rollover.
So this often seen odd stack-initialising (against performance)
may be seen as a protection against unwanted stack under/overrun.

> in real mode pop can experience the following exception.
> Interrupt 13 if any part of the operand would lie outside of the
> effective address space from 0 to 0FFFFH

yeah, that's what Intel-books tell :) seems Intel thinks that
'POP reg' haven't got an operand and so wont raise EXC-0x0d.

Realmode exception 0x0D is called and work as "Segment-Overrun" which
work the same way as exc-0x0C above except that an aligned rollover
wont raise an exception.
So a short jump at the very end of a segment can jump quite far :)

FFFE EB 00 jmp 0000 ;really goes backwards to 0000

> What does it mean by "the operand"? Is it talking solely about pop to
> memory or could an exception be generated in real mode for pop to a
> register perhaps because the stack underflows?

The Operand come into play for POP [mem], and here an int13 can occure,
and as worst case in addition to an int12.
__
wolfgang


Rod Pemberton

unread,
Apr 9, 2012, 12:01:38 PM4/9/12
to
<pe...@nospam.demon.co.uk> wrote in message
news:133395...@nospam.demon.co.uk...
> In article <jltbm7$prg$1...@speranza.aioe.org>
...


> RBIL

Nice call.

> a PUSH MEM or POP MEM instruction contains an invalid bit
> encoding in the second byte

He had me scratching my head on that one ... I pulled out the 286 and 86
manuals too.

I guess that note is for POP encoding 8F /0, but only if someone
manually encodes the instruction and makes a mistake. I.e., if one
encodes /1 , /2 , /3 , /4 , /5 , /6 or /7 instead of /0 ? Yes or no?
Assemblers take care of the correct encoding for us.


Rod Pemberton




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

unread,
Apr 10, 2012, 2:48:22 PM4/10/12
to
In article <jlv151$4vf$1...@speranza.aioe.org>
Agreed -- long live decent assemblers. But I was intrigued and so
decided to mess with those bit encodings to see what happened.
Looking in my Rector & Alexy 8086 book I saw that the 'pop mem/reg'
encoding was 8F (mod 000 r/m) and that 001 to 111 were "not used".
Below is a LST file produced by MASM4 (yes I know...):

-- pop.asm LST file --

0000 code segment public 'code'
assume cs:code, ds:code
0100 org 100h
0100 ???? foo dw ?
0102 start:
0102 8F 06 0100 R pop [foo]

; 8f, 06, 00, 01
; 8f, 00000110b, 0, 1

0106 8F 0E 00 01 db 8Fh, 00001110b, 0, 1
010A 8F 16 00 01 db 8Fh, 00010110b, 0, 1
010E 8F 1E 00 01 db 8Fh, 00011110b, 0, 1
0112 8F 26 00 01 db 8Fh, 00100110b, 0, 1
0116 8F 2E 00 01 db 8Fh, 00101110b, 0, 1
011A 8F 36 00 01 db 8Fh, 00110110b, 0, 1
011E 8F 3E 00 01 db 8Fh, 00111110b, 0, 1

012A code ends
end
-- end LST file --

When this was linked and shown in debug, we see:

C:\ASM>debug pop.com
-u
0C48:0100 0000 ADD [BX+SI],AL
0C48:0102 8F060001 POP [0100]
0C48:0106 8F0E0001 POP [0100]
0C48:010A 8F160001 POP [0100]
0C48:010E 8F1E0001 POP [0100]
0C48:0112 8F260001 POP [0100]
0C48:0116 8F2E0001 POP [0100]
0C48:011A 8F360001 POP [0100]
0C48:011E 8F3E0001 POP [0100]
-q
C:\ASM>

The code is obviously not executable (so I didn't try!) but it would
appear the DEBUG believes that these instructions are all valid POPs,
though that is probably more a statement about MS DEBUG than 8086
reality.

Comments?

James Harris

unread,
Apr 27, 2012, 3:53:19 PM4/27/12
to
On Apr 9, 1:13 am, ArarghMail204NOS...@nospicedham.NOT.AT.Arargh.com
wrote:
> On Sun, 8 Apr 2012 14:01:12 -0700 (PDT), James Harris
>
> <james.harri...@nospicedham.gmail.com> wrote:
> >I am having trouble interpreting an Intel instruction definition. Can
> >you make sense of it? The question is if in real mode I pop the stack
> >to a register what exceptions are possible? According to
>
> >  http://pdos.csail.mit.edu/6.828/2007/readings/i386/POP.htm
>
> >in real mode pop can experience the following exception.
>
> >  Interrupt 13 if any part of the operand would lie outside of the
> >effective address space from 0 to 0FFFFH
>
> >What does it mean by "the operand"? Is it talking solely about pop to
> >memory or could an exception be generated in real mode for pop to a
> >register perhaps because the stack underflows?
>
> push and pop ALWAYS reference memory, at least once.  Twice if you
> push or pop to a memory location.  After all, where do you think the
> stack lives?

I know where the stack lives! That wasn't what I was asking.

> "the operand" is that part of the stack that is about to be
> referenced by the pop instruction.

That is ONE operand. The other is where the value from the stack is
copied to. One is implicit, the other explicit. For example, in

pop word [si]

the si reference also specifies an operand. The Intel instruction
definition is poor in specifying "the operand" when there are two.

In the example above, if SI = 0xffff before the instruction would that
also require a memory access out of the effective address space?

Nevertheless, I suspect that Intel really so mean the implicit stack
operand, as you suggest.

> IIRC, in real mode, if SP=0FFFEh then pop gets the exception.

You may be right but that value seems unlikely to cause the exception
mentioned. If SP = 0xfffe then wouldn't the entire 2-byte value from
the stack be loadable? SP would wrap to zero afterwards but the
instruction definition doesn't object to that. I guess you meant
0xffff?

Of course, the corresponding issue for the push instruction would be
if SP was 1 before push was executed (SP would be decremented to
0xffff before the memory transfer). Interestingly they do state that
SP = 1 is invalid but rather than generate an exception they say that
it will shut down the CPU!

http://pdos.csail.mit.edu/6.828/2007/readings/i386/PUSH.htm

James

James Harris

unread,
Apr 27, 2012, 4:07:11 PM4/27/12
to
On Apr 9, 11:19 am, "wolfgang kern" <nowh...@never.at> wrote:
> James Harris wrote:
> >I am having trouble interpreting an Intel instruction definition. Can
> > you make sense of it? The question is if in real mode I pop the stack
> > to a register what exceptions are possible? According to
> >  http://pdos.csail.mit.edu/6.828/2007/readings/i386/POP.htm
>
> I assume true real mode rather than VM86,
> "POP reg16"
> can raise exception 0x0c if SP was 0xFFFF (stack bound crossing),

Thanks for pointing out the existence of interrupt 12 - Stack
Exception.

http://pdos.csail.mit.edu/6.828/2007/readings/i386/s09_08.htm

It makes it even more strange that

1. Intel say that interrupt 13 can be generated by pop.

2. Intel don't say that pop can generate interrupt 12!

> and it also should if SP was 0xFFFE and become 0 after the POP,
> but I remember early 286 which allowed this aligned stack-rollover.
> So this often seen odd stack-initialising (against performance)
> may be seen as a protection against unwanted stack under/overrun.

From the instruction definition it doesn't sound like that the read
from SP:0xfffe would generate any interrupt.

> > in real mode pop can experience the following exception.
> >  Interrupt 13 if any part of the operand would lie outside of the
> > effective address space from 0 to 0FFFFH
>
> yeah, that's what Intel-books tell :)  seems Intel thinks that
> 'POP reg' haven't got an operand and so wont raise EXC-0x0d.
>
> Realmode  exception 0x0D is called and work as "Segment-Overrun" which
> work the same way as exc-0x0C above except that an aligned rollover
> wont raise an exception.
> So a short jump at the very end of a segment can jump quite far :)
>
> FFFE  EB 00    jmp 0000     ;really goes backwards to 0000
>
> > What does it mean by "the operand"? Is it talking solely about pop to
> > memory or could an exception be generated in real mode for pop to a
> > register perhaps because the stack underflows?
>
> The Operand come into play for POP [mem], and here an int13 can occure,
> and as worst case in addition to an int12.

Interestingly, I can see that in the 386 manual Intel state

"Real Address Mode Exceptions - Interrupt 13 if any part of the
operand would lie outside of the effective address space from 0 to
0FFFFH"

on many instructions. It seems to be a standard text.

James
0 new messages