8086平台读取BIOS计时滴答 需保留多少原有代码?
精简8086小模型下BIOS计时滴答读取函数
先直接给出精简后的代码,再拆解优化细节:
static clock_t clock(void); #pragma aux clock = \ "mov ax, [0x40:0x6C]" \ parm [ ax ] \ modify [ ax ];
优化细节拆解
移除
pushf/popf和cli/sti
你读取的是BIOS计时器的16位低字(0x40:0x6C),8086的16位mov指令是原子操作,执行过程不会被中断打断,完全不需要关中断(cli)和开中断(sti)。既然不需要修改标志寄存器的IF位,保存/恢复标志位的pushf/popf自然也可以删掉。用段直接寻址替代DS切换
原代码通过切换DS到0x0040来访问BIOS数据区,现在直接用8086的段:偏移寻址语法[0x40:0x6C],一步到位读取目标地址的值,省去了push ds、mov ax, 0x0040、mov ds, ax、pop ds这四条冗余指令。去掉BX寄存器的冗余使用
原代码用BX暂存偏移地址0x006C,现在直接在寻址中指定偏移,不需要占用BX寄存器,所以modify [ ax bx ]可以简化为modify [ ax ]。
补充说明
如果之后需要读取完整的32位计时器值(低字0x40:0x6C+高字0x40:0x6E),这时候就必须保留cli/sti和pushf/popf——因为两次16位读取之间可能被时钟中断打断,导致读取的高低字不匹配。但仅读取16位低字的场景下,当前精简版完全安全可靠。
内容的提问来源于stack exchange,提问作者Benjamin Penney
相关产品推荐
相关产品推荐

