X86 Asm - CLI, STI

Started by
22 comments, last by markr 19 years, 8 months ago
From various things I've read, it appears the CLI and STI instructions are problematic, so I thought I'd ask if anyone has tips, tricks or recommendations about using them in user mode or kernel mode.
"I thought what I'd do was, I'd pretend I was one of those deaf-mutes." - the Laughing Man
Advertisement
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.

StevieDon't follow me, I'm lost.
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.
"I thought what I'd do was, I'd pretend I was one of those deaf-mutes." - the Laughing Man
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)
You can in the vm86 mode (DOS emulation) so any 16bit program that uses

clihlt


will halt Windows.
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?
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]
Ra
It'll halt Win9x even outside of DOS emulation mode. A proper operating system will not let any user program execute cli.

Win9x lets any user program do so.
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.
char a[99999],*p=a;int main(int c,char**V){char*v=c>0?1[V]:(char*)V;if(c>=0)for(;*v&&93!=*v;){62==*v&&++p||60==*v&&--p||43==*v&&++*p||45==*v&&--*p||44==*v&&(*p=getchar())||46==*v&&putchar(*p)||91==*v&&(*p&&main(0,(char**)(--v+2))||(v=(char*)main(-1,(char**)++v)-1));++v;}else for(c=1;c;c+=(91==*v)-(93==*v),++v);return(int)v;}  /*** drpizza@battleaxe.net ***/
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.
char a[99999],*p=a;int main(int c,char**V){char*v=c>0?1[V]:(char*)V;if(c>=0)for(;*v&&93!=*v;){62==*v&&++p||60==*v&&--p||43==*v&&++*p||45==*v&&--*p||44==*v&&(*p=getchar())||46==*v&&putchar(*p)||91==*v&&(*p&&main(0,(char**)(--v+2))||(v=(char*)main(-1,(char**)++v)-1));++v;}else for(c=1;c;c+=(91==*v)-(93==*v),++v);return(int)v;}  /*** drpizza@battleaxe.net ***/

This topic is closed to new replies.

Advertisement