Code Comments
Programming Forum and web based access to our favorite programming groups.Using an operand override with a segment push in RM seems to push the lower 16bits of EFlags onto the stack as well as the segment register i.e. db 66 push ds pop ax pop bx will produce ax=ds, bx=flags on my P3. Is this normal or just an example of 'undefined' -- Cranky
Post Follow-up to this messageCranky wrote: > Using an operand override with a segment push in RM seems to push the > lower 16bits of EFlags onto the stack as well as the segment register > i.e. > > db 66 > push ds > pop ax > pop bx > > will produce ax=ds, bx=flags on my P3. Is this normal or just an > example of 'undefined' May be "coincidence"... On my P4, if I do what you do, I see flags. If I push 0FFFFFFFFh first, and pop it, *and* if I run the code "at speed" rather than stepping through it (so probably not interrupted), I see 0FFFFh. I suspect that the high word may be unchanged by the 32-bit push segreg, and you're seeing flags because they were put there previously by a hardware int. Would further experimentation on your P3 show this? I realize that some of us "just like to know", but why would you *care*? Planning to actually *do* this? :) (if so, I'd go with "undefined", just to be sure!) Best, Frank
Post Follow-up to this message"Cranky" wrote: > Using an operand override with a segment push in RM seems to push the > lower 16bits of EFlags onto the stack as well as the segment register > i.e. > db 66 > push ds > pop ax > pop bx > > will produce ax=ds, bx=flags on my P3. Is this normal or just an > example of 'undefined' Stack will contain previous used data, and even there is a good chance that a previous IRQ pushed the flags as the last item, I wouldn't rely on this by any means. you can try: cli ... push 0 sti ... pop cx db 66 ;this just effects SP (-4 instead of -2) push DS ;only 16 bits are copied to the stack pop ax pop bx cmp bx,0 ;may be nz if your code were interrupted inbetween push 0 ... pop cx ;but it should read zero if no IRQ occured. __ wolfgang
Post Follow-up to this message"Cranky" <spamtrap@crayne.org> wrote in message news:e7f84580-90d3-4416-9fd3-b22663ee7dbd@c19g2000prf.googlegroups.com... > Using an operand override with a segment push in RM seems to push the > lower 16bits of EFlags onto the stack as well as the segment register > i.e. > > db 66 > push ds > pop ax > pop bx > > will produce ax=ds, bx=flags on my P3. Is this normal or just an > example of 'undefined' > Using "db 0x66" - operand size override, you told "push" to push a 32-bit operand onto a 16-bit stack: ... ELSE StackAddrSize = 16 IF OperandSize = 16 THEN .. ELSE (* OperandSize = 32 *) SP <- (SP - 4); SS:SP <- SRC; (* Push doubleword *) FI; FI; But, DS is only 16-bits so "push" must get 16 more bits from somewhere... For FS or GS, Intel defines the outcome of pushing the additional 16-bits: "If the source operand is the FS or GS and its size is less than the address size of the stack, the zero-extended value is pushed on the stack." Rod Pemberton
Post Follow-up to this messageFrank Kotler wrote: > Cranky wrote: > > May be "coincidence"... That's what it is, it's just pushing the segment register but adjusting the stack count by 4 instead of 2. > I realize that some of us "just like to know", but why would you *care*? I guess I could live in ignorant bliss by not asking, but the question would always be nagging me in the back of my mind. > Planning to actually *do* this? Just curious, and now I know, thanks. -- Cranky
Post Follow-up to this messageOn Apr 1, 7:53 pm, "Wolfgang Kern" <spamt...@crayne.org> wrote: > "Cranky" wrote: > > > Stack will contain previous used data, and even there is a good chance > that a previous IRQ pushed the flags as the last item, I wouldn't rely > on this by any means. > > you can try: > cli > ... > push 0 > sti > ... > pop cx > db 66 ;this just effects SP (-4 instead of -2) > push DS ;only 16 bits are copied to the stack > pop ax > pop bx > cmp bx,0 > ;may be nz if your code were interrupted inbetween push 0 ... pop cx > ;but it should read zero if no IRQ occured. > > __ > wolfgang Yep, thanks Wolfgang, nice example. I saw from Frank's post what was happening, much the same as sub sp,2 push ds My question now reminds of an old saying, "Better to remain silent and be thought a fool than to speak out and remove all doubt." :) -- Cranky
Post Follow-up to this messageCranky wrote: ... > My question now reminds of an old saying, "Better to remain silent and > be thought a fool than to speak out and remove all doubt." :) I'm rather glad you asked the question! Rod posted, from the manual, that fs and gs are zero extended (why do they single out fs and gs? aren't they "all the same"?). I can't see any sign of that happening. Working in dosemu, working in DEBUG, I see either "unchanged" (if I "g" past it) or "flags" (if I "t" through it). Running it "native", however, it seems always "unchanged", even with a delay loop long enough that I'd expect a timer interrupt to have occurred. But I got a little "distracted"... In order to have a known value on the stack - at sp +2 - I pushed a known dword: o32 push 55AA55AAh Nasm warns about word value exceeds bounds - then *ignores* the "excess" and picks up the *next* two bytes to push! I expected that to work! push dword 55AA55AAh does what I intended. I guess that isn't a "bug" - the o32 only tells Nasm to emit the prefix (if we're in 16-bit code - shouldn't do anything in 32-bit code), and didn't really say to expect a dword immediate... okay... I expected it to do the same thing. Guess I haven't got enough experience with Nasm... This time, pay attention to the warning! This doesn't affect your code - o32 push ds (or fs) does the "right thing". (you explicitly say db 66h anyway...) Rod quotes the manual: SP <- (SP - 4); SS:SP <- SRC; (* Push doubleword *) If we assume that "SRC" is 16 bits, this would imply that sp + 2 is "unchanged"... wouldn't it? Seems to conflict with: "If the source operand is the FS or GS and its size is less than the address size of the stack, the zero-extended value is pushed on the stack." Anyway, after updating dosemu to Nasm 2.02 (I was running a Known Buggy version) to try to get "o32 push imm32" to do what I wanted (no), I'm still seeing "unchanged" outside of DEBUG, and flags stepping through it. Maybe the "zero extended" only applies to a 32-bit "push fs" in 32-bit code... I may try that. I'm tempted to try it from a bootsector, just to make sure dosemu isn't messin' with me. Never trust an OS, especially an emulated one! Probably won't get to that... I still don't know why we care, but I learned something about Nasm, and possibly discovered a deviation between experimentation and the Fine Manual... there are benefits to "I just like to know"! Best, Frank
Post Follow-up to this messageOn Apr 2, 5:04 am, Frank Kotler <spamt...@crayne.org> wrote: > Cranky wrote: > > ... > > > I'm rather glad you asked the question! Rod posted, from the manual, > that fs and gs are zero extended (why do they single out fs and gs? > aren't they "all the same"?). Well here's what I found out on my P3, 16 Bit RM With operand size prefix and push segment the equivalent op is similar to.. SUB SP,2 PUSHW CS ;or other seg reg This applies to all 6 segment registers. 32 Bit PM 1. With push segment (no 66h) we get the same as above. 2. If we add the operand size prefix then the segment registers are zero extended. Again this applies to all 6 segment registers. Of course, this has only been tested on my P3. An AMD Sempron 3500+ would seem to zero extend in 16 bit RM. But I guess it probably doesn't really matter all that much in the end, except for solving my curiosity. :) -- Cranky
Post Follow-up to this message"Frank Kotler" <spamtrap@crayne.org> wrote in message news:0kyIj.6454$Ps1.4136@trndny08... > Cranky wrote: > > I'm rather glad you asked the question! Rod posted, from the manual, > that fs and gs are zero extended (why do they single out fs and gs? > aren't they "all the same"?). I can't see any sign of that happening. > Working in dosemu, working in DEBUG, I see either "unchanged" (if I "g" > past it) or "flags" (if I "t" through it). Running it "native", however, > it seems always "unchanged", even with a delay loop long enough that I'd > expect a timer interrupt to have occurred. > Frank, When I first read your 6:13AM post yesterday afternoon, I found it _very_ odd that the cpu wouldn't actually push 32-bits for "db 66, push ds"... So, I decided to check later. Well, I'm _shocked_ to find out that a cpu doesn't push 32-bits for "db 0x66, push ds"!!!! Intel Pentium II 450Mhz upper 16-bits: 0x7106 AMD K6-2 500Mhz upper 16-bits: 0 Intel Pentium MMX 233Mhz upper 16-bits: 0 For the P2, 7106h appears to be lower 16-bits of EFLAGS for RM DOS v7.10 (with TF set)... I'm not sure why the EFLAGS bits for '7' are set here... It looks more like v86, but it's not - perhaps TF issue? Earlier Cranky asked: Looking like 'not well defined' or perhaps 'non-critical'... Rod Pemberton
Post Follow-up to this messageRod Pemberton <spamtrap@crayne.org> wrote in part: > When I first read your 6:13AM post yesterday afternoon, I found it > _very_ odd that the cpu wouldn't actually push 32-bits for "db 66, > push ds"... So, I decided to check later. Well, I'm _shocked_ to > find out that a cpu doesn't push 32-bits for "db 0x66, push ds"!!!! 'scuse me, but why are you _shocked_? DS doesn't _have_ 32 bits to push. -- Robert
Post Follow-up to this message
Show a Printable Version
Email This Page to Someone!
Receive updates to this thread
Powered by vBulletin
Copyright 2000-2006 Jelsoft Enterprises Limited.