原创 开关中断命令解释

2010-1-7 13:54 2620 1 1 分类: MCU/ 嵌入式

看到两个宏:


#if      OS_CRITICAL_METHOD == 1
#define  OS_ENTER_CRITICAL()  asm  CLI             /* Disable  interrupts       */
#define  OS_EXIT_CRITICAL()   asm  STI                /* Enable  interrupts
        */


#endif


问:在asm中,常用 CLI 和 STI 搭配使用,是什么情况下才使用的???



答:CLI是禁用中断,当你修改中断向量或修改堆栈指针时一般要禁用它,因为在进行这些时如果有中断产生,那么会破坏当前的环境,造成程序崩溃。当你干完这些时就可以STI了。以上所说适用于16位DOS中断。在32位下我不太清楚:(


问:能给我一个实例吗?多谢!


答:

程序员可以改变段地址和偏移地址,但是在这个过程中如果需要改变段寄存器SS和SP必须禁止中断,当改变完成后再恢复中断(也就是说在cli指令后需要有与其配对的sti指令,否则计算机--最常见的反应就是--死机~~~)
为什么要这样做?举个例子:
当你写了一段程序并且运行它时,系统中运行的程序并不只是它一个!最简单的例子--计时器(timer),计算机电路中它每秒钟发生18次中断。就是在你等待键盘输入的时候它也会发生~这是系统会在堆栈中保存下一条指令的地址和所有的寄存器,然后转到中断处理程序(比方说刷新时间的显示)。然后退出中断,恢复寄存器并转到刚才保存下的指令地址。
比方说,下面这个程序段(没有屏蔽中断):
(1) mov ax,100h
(2) mov ss,ax
(3) mov sp,200h
假设在执行完指令(2)时产生了一个计时器中断。这时SS等于100h,但是SP还没有来得及改变。这样就是说堆栈的段地址正确,但偏移地址还是原先堆栈的偏移地址(假设SP=0FFFEh)。系统会在SS=100h,SP=0FFFEh的内存地址处保存所有寄存器和下一条指令地址等等需要保存的信息。如果这个地址(100h、0FFFEh)上有什么重要的信息,这样的结果就可能覆盖系统的一些重要数据!你猜它会怎么做??:)

下面是两条规则:
1)在改变SS:SP之前,必须用cli指令屏蔽中断,然后等操作执行完立即用sti指令恢复
2)SS:SP需要设置在空闲的内存地址,不要建立在其他的程序(尤其是系统的)代码区

正确的写法:
cli
mov ax,0B900h
mov ss,ax
mov sp,100h
sti
PARTNER CONTENT

文章评论0条评论)

登录后参与讨论
我要评论
0
1
关闭 站长推荐上一条 /2 下一条