刚刚接触Win32汇编,写了一个发声的小程序,代码如下:
- Assembly code
; 只要向地址61h位控制寄存器的0和1位发送高电平便能驱动扬声器.386.model flat,stdcalloption casemap:noneinclude kernel32.incincludelib kernel32.lib.code;==========================;发声子程序;==========================beep proc PUSHAD ; 保存寄存器 ;======================== ; 61h ;======================== IN AL,61h ; 读取控制寄存器中的内容 MOV AH,AL ; 保存一个副本到AH中,用于后面恢复控制寄存器 OR AL,00000011b ; 低两位处理 OUT 61h,AL ;======================== ;延时 ;======================== MOV ECX ,0fffff5h .repeat NOP .untilcxz ;======================== ;把控制器中的内容还原,关闭扬声器 ;======================== MOV AL,AH OUT 61h,AL POPAD RETbeep endpstart: invoke beep invoke ExitProcess,0end start
程序生成后,执行发现,出现下面的错误
谁能解释一下,这是什么原因吗?我在另外的一台电脑上试过也是这个错误!
------解决方案--------------------------------------------------------
in/out指令在windows NT中属于特权指令,无法正常完成,如果要执行,有几种办法:
A 在win9x下执行
B 在DOS虚拟机中执行
C 在NT中加载驱动执行
D 在某些未打安全补丁较老的NT版本中通过调试API从Ring3跳至Ring0执行
E 使用开放接口的库来完成,比如WinIO
内核汇编中有C完整的例子