Sign in to follow this  

X86 Asm - CLI, STI

This topic is 4859 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Don’t know what you mean by ‘problematic’.

It may be some Operating Systems (of the NT variety) don’t like their background work interfered with.

When CLI is executed, the processor recognises no maskable interrupts. This means no hardware (ie disk, keyboard, timer) can interrupt the CPU.

STI restores the CPU to recognise maskable interrupts.

The only time I have found it necessary to use these instructions is when changing the location of the stack. In 16-bit mode DOS this takes 4 instructions and the CLI/STI bracketed them.

Some pre-emptive OS’s use a timer to get control back from each task.

Also some hardware interfaces (the RS232, for example) rely heavily on fixed timing for doing what they do and will disable interrupts for the critical portion of the process.

If you are advised not to do it, but find you absolutely have to, keep the lock as short as possible.

Hope this helps.

Share this post


Link to post
Share on other sites
Quote:
Original post by stevie56
Don’t know what you mean by ‘problematic’.

Yeah, problematic isn't accurate, but I wanted to keep the question general. I've read a few news group posts via google, where the respondents made comments indicating that CLI could cause problems in kernel mode.

If you are familiar with the book "Undocumented NT", the authors describe a prolog/epilog sequence of instructions for trapping page faults in an installed callgate function. I don't have their code at hand, but I recall they use CLI and I've read on the ng that this wasn't necessarily optimal. From what I've been able to work out, their code isn't adequate for trapping faults on W2K (they seem to approach the issue using an inaccurate definition of the KTRAP_FRAME structure). I've worked out a better prolog/epilog sequence than theirs, but that doesn't mean I've stopped looking for ways to improve it. Thus, this thread.

Quote:
Original post by stevie56
It may be some Operating Systems (of the NT variety) don’t like their background work interfered with.

Yes, my interest is NT/2K/XP specific.

Quote:
Original post by stevie56
When CLI is executed, the processor recognises no maskable interrupts. This means no hardware (ie disk, keyboard, timer) can interrupt the CPU.

Ok. I read the Intel docs before posting and the entry for CLI mentions "maskable interrupts" but doesn't say what that means.
What happens if hardward signals one just the same? Is it queued in some fashion?

Quote:
Original post by stevie56
STI restores the CPU to recognise maskable interrupts.

The only time I have found it necessary to use these instructions is when changing the location of the stack. In 16-bit mode DOS this takes 4 instructions and the CLI/STI bracketed them.

Some pre-emptive OS’s use a timer to get control back from each task.

Also some hardware interfaces (the RS232, for example) rely heavily on fixed timing for doing what they do and will disable interrupts for the critical portion of the process.

If you are advised not to do it, but find you absolutely have to, keep the lock as short as possible.

Hope this helps.


Yes, it helps, thanks. STI seems a lot more straight forward, but it seems paired with CLI so I thought I would ask about them that way.

Share this post


Link to post
Share on other sites
AFAIK CLI and STI are privileged instructions that can only be executed in kernel space (ring 0), so you can't even use them in normal Windows programs (you will likely get some kind of exception)

Share this post


Link to post
Share on other sites
Quote:


What happens if hardward signals one just the same? Is it queued in some fashion?



Yes. The interrupt controller will keep the interrupt line of the CPU asserted until it receives an End-Of-Interrupt signal, which will only be sent by the interrupt handler.

Quote:

You can in the vm86 mode (DOS emulation) so any 16bit program that uses

cli
hlt

will halt Windows.


No it won't. In V8086 mode, just as in protected mode, cli at a privelege level lower than IOPL causes a trap. The instruction will then be emulated by the MS-DOS emulator.


LessBread, are you trying to write code to run in kernel mode?

Share this post


Link to post
Share on other sites
Quote:
Original post by bakery2k1
No it won't. In V8086 mode, just as in protected mode, cli at a privelege level lower than IOPL causes a trap. The instruction will then be emulated by the MS-DOS emulator.
I thought that until a couple weeks ago when I tried it. It'll halt Win9x, not sure about the rest. I'm betting someone got fired. [wink]

Share this post


Link to post
Share on other sites
Windows 9x is always *in* DOS emulation mode of some kind or another, as it's always got large chunks of DOS still resident.

It's hardly representative of what real OSes do.

cli and sti can only properly be called from kernel mode. You can't call them from user mode (nor would it be particularly useful to do so), and when calling them from kernel mode you should enable interrupts as soon as possible so that the system doesn't lock up.

I haven't heard that they're particularly "problematic" or anything like that, though.

Share this post


Link to post
Share on other sites
Quote:
Ok. I read the Intel docs before posting and the entry for CLI mentions "maskable interrupts" but doesn't say what that means.

It means every interrupt (be it generated by hardware or "int xx") except for the NMI.

The NMI is usually maskable through the BIOS NMI AND gate, but the processor itself has no way of masking it.

Share this post


Link to post
Share on other sites
Quote:

It can still do the right thing even within an interrupt handler?

I didn't think that'd work.


I don't see what the problem could be.

How would the state of the interrupt flag affect what the interrupt handler could do? It affects only whether or not the handler is entered.

Share this post


Link to post
Share on other sites
As previous posters said: CLI/STI are only interesting to kernel mode programming.

CLI for a long time (> 1 ms) will mean that other things that need to run (mouse movement, screen sync, audio buffers, etc) will not get time when they need it, so your system will become more unreliable. This is a major reason Win9x/ME can't be used for much; most drivers use CLI willy-nilly.

CLI can ensure atomicity (no other code will run and compete with your data structures) if you're guaranteed to be on a single-CPU system. If you can be on multiple CPUs (including HyperThreading enabled) then you need to first CLI, and then compare/exchange some memory location until it was zero, and you set it to 1; this is known as a spinlock. Set it back, and restore interrupts when you're done. Acquiring a spinlock from within an interrupt handler is possible, but of course, you should RESTORE interrupts, not ENABLE them when un-acquiring the spinlock, in the case they were disabled when you acquired it in the first place.

However, it's more portable to just use the kernel spinlock primitives, and do as much as you can out of a DPC rather than directly from an interrupt handler.

Share this post


Link to post
Share on other sites
I can't see how CLI / STI are useful even in kernel-mode programming, because on a multiprocessor system (or hyperthread), they don't actually stop interrupts from interrupting the other processor.

Instead just use proper locking as specified by the OS to protect whatever it is you're trying to do with interrupts disabled.

Having another processor messing with things is at least as disruptive as having an interrupt happening - and you can't stop it with CLI.

Not to mention the fact that these are ia32 instructions which don't even exist on other CPUs (although of course they have equivalents).

Just use kernel-mode locks for your OS.

Mark

Share this post


Link to post
Share on other sites
Quote:
Original post by bakery2k1
Yes. The interrupt controller will keep the interrupt line of the CPU asserted until it receives an End-Of-Interrupt signal, which will only be sent by the interrupt handler.


Ok. Does the EOI signal come about from the iret instruction (at the end of the interrupt handler)?

Quote:
Original post by bakery2k1
LessBread, are you trying to write code to run in kernel mode?


The code is already written.

Share this post


Link to post
Share on other sites
Quote:
Original post by LessBread
Ok. Does the EOI signal come about from the iret instruction (at the end of the interrupt handler)?

I vaguely remember something like outputting 20h to port 20h... it's been MANY years, so don't count on that being accurate. The documentation of the interrupt controller chip is probably the best place to look (or perhaps a quick glance at Linux).

Share this post


Link to post
Share on other sites
Quote:
Original post by hplus0603
As previous posters said: CLI/STI are only interesting to kernel mode programming.

CLI for a long time (> 1 ms) will mean that other things that need to run (mouse movement, screen sync, audio buffers, etc) will not get time when they need it, so your system will become more unreliable. This is a major reason Win9x/ME can't be used for much; most drivers use CLI willy-nilly.

CLI can ensure atomicity (no other code will run and compete with your data structures) if you're guaranteed to be on a single-CPU system. If you can be on multiple CPUs (including HyperThreading enabled) then you need to first CLI, and then compare/exchange some memory location until it was zero, and you set it to 1; this is known as a spinlock. Set it back, and restore interrupts when you're done. Acquiring a spinlock from within an interrupt handler is possible, but of course, you should RESTORE interrupts, not ENABLE them when un-acquiring the spinlock, in the case they were disabled when you acquired it in the first place.

However, it's more portable to just use the kernel spinlock primitives, and do as much as you can out of a DPC rather than directly from an interrupt handler.


Ok. That's helpful. I see now why it was in the code and why it was frowned on in the ng. Thanks. Thanks also Dr. Pizza, bakery2k1 and markr.


Share this post


Link to post
Share on other sites
Quote:
Original post by Namethatnobodyelsetook
I vaguely remember something like outputting 20h to port 20h... it's been MANY years, so don't count on that being accurate. The documentation of the interrupt controller chip is probably the best place to look (or perhaps a quick glance at Linux).


Ok. Maybe I'll do that.

Share this post


Link to post
Share on other sites
Quote:
How would the state of the interrupt flag affect what the interrupt handler could do? It affects only whether or not the handler is entered.

Yes, but *does* the handler get entered from a "int xx" when interrupts are disabled?

Share this post


Link to post
Share on other sites
Quote:
I can't see how CLI / STI are useful even in kernel-mode programming, because on a multiprocessor system (or hyperthread), they don't actually stop interrupts from interrupting the other processor.

But do they have to? The point of disabling interrupts is to make sure the processor doesn't get interrupted when it's dealing with an interrupt, not to protect shared resources.

Share this post


Link to post
Share on other sites
Quote:
Original post by DrPizza
Quote:
How would the state of the interrupt flag affect what the interrupt handler could do? It affects only whether or not the handler is entered.

Yes, but *does* the handler get entered from a "int xx" when interrupts are disabled?


Yes.

Share this post


Link to post
Share on other sites
Quote:
Original post by DrPizza
But do they have to? The point of disabling interrupts is to make sure the processor doesn't get interrupted when it's dealing with an interrupt, not to protect shared resources.


I disagree. Being interrupted from an interrupt is just a special case of protecting shared resources.

In fact it's fine if you get interrupted from an interrupt, as long as it's not the same one and doesn't share any resources (and the stack doesn't overflow of coure).

It's just a special case.

Mark

Share this post


Link to post
Share on other sites

This topic is 4859 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this