麻豆小视频在线观看_中文黄色一级片_久久久成人精品_成片免费观看视频大全_午夜精品久久久久久久99热浪潮_成人一区二区三区四区

首頁 > 編程 > ASM > 正文

CB和匯編混合編程

2019-11-17 05:43:46
字體:
來源:轉載
供稿:網友
  我在寫定時提醒 時碰到一個問題:怎么發聲?我開始是用 32 位 Windows 的 API 函數 MessageBeep( -1 ); 那聲音又小又難聽。原來在 16 位的 Windows API 中有的一套 PlaySound 的函數在 32 位 Windows 中又取消了, DOS 下的 Sound 函數更是早就不能用了。

幸好我對硬件還算了解,知道 PC Speaker 的聲音是通過系統中的定時計數芯片 8253/8254 產生的,只要通過硬件端口訪問芯片就可以產生想要的聲音了。 問題在于 Windows 是工作在保護模式下,大多數硬件端口都要在特權級0(PL0, 這是搞硬件的人的說法,后來我才知道在搞 OS 和 Driver 的人中是叫 Ring 0 的, 這才比較正確,因為假如不是 Intel 的 CPU 可能就不叫 PL 了)中, 即操作系統核心態中,才可以訪問(比如硬盤口,訪問時是不會出錯,但結果不正確), 這也就意味著要寫成驅動程序的形式,天啊! VxD 和 WDM 我都不會,怎么辦? 事實上沒有這么困難,像 PC Speaker 這種無傷大體的端口, Windows 是不保護的, 即在用戶態下也可以正常訪問。

現在還有一個問題就是用什么語句訪問端口? DOS 中 C 語言里的那幾個端口操作函數在 Windows 中都取消了,只好用匯編。我開始是用 ASM 語句插入匯編代碼,結果發現 BCB 在編譯時碰到 ASM 時會把 BCB 文件編譯成一個巨大的 ASM 文件, 再重新啟動匯編程序匯編,速度太慢。最后采用了我在 DOS 編程時常用的方法, 做一個單獨的 ASM 文件加入工程文件中。

下面是兩個用于發聲的函數,最前面聲明了兩個外部 C 調用形式的函數, 是兩個用匯編寫的字節端口輸入/輸出函數,注重:在 C++ 中一定要注重外部函數應為 C 調用形式。程序中多處強制類型轉換是為了不出現警告,我對程序一向要求 Error/Warning/Hint 全為 0。


extern "C" {
Byte InPortB( int aPort );
void OutPortB( int aPort, Byte aValue );
}

void __fastcall Sound( int aFreq )
{
if ( ( aFreq >= 20 ) && ( aFreq <= 20000 ) )
{
aFreq = 1193181 / aFreq;
Byte b = InPortB( 0x61 );
if ( ( b & 3 ) == 0 )
{
OutPortB( 0x61, Byte( b 3 ) );
OutPortB( 0x43, 0xb6 );
}
OutPortB( 0x42, ( Byte )aFreq );
OutPortB( 0x42, ( Byte )( aFreq >> 8 ) );
}
}

void __fastcall NoSound( void )
{
Byte b = Byte( InPortB( 0x61 ) & 0xfc );
OutPortB( 0x61, b );
}


下面是兩個端口 I/O 的函數的匯編源程序,即定時提醒(Alarm)中的 IOPortB.asm 文件的全部內容,是在 BCB 產生的 ASM 文件基礎上作了一點點的優化。 注重:
1 、最前面的 .386p 必不可少,指定用 32 位保護模式,至于 modal flat 我也不太明白是 What ,跟 16 位時的 tiny, small... 不同,大概是指用 32 位保護模式的平坦地址間模式吧;
2 、在 32 位保護模式中, CS/ip 為 32 位,參數在棧中的位置與 16 位時不同;
3 、最后的 public 也不可少,前綴的下劃線也是必須的,另外記得用大小寫敏感方式匯編。


.386p
model flat
_TEXT segment dWord public use32 ''CODE''

_InPortB PRoc near
push ebp
mov ebp, esp
mov dx, word ptr [ebp + 8]
in al, dx
pop ebp
ret
_InPortB endp

_OutPortB proc near
push ebp
mov ebp, esp
mov dx, word ptr [ebp + 8]
mov al, byte ptr [ebp + 12]

out dx, al
pop ebp
ret
_OutPortB endp

public _InPortB
public _OutPortB

_TEXT ends

end


注重:此法在 Windows NT 上行不通,因為 Windows NT 保護了所有的端口,必須用 WDM,連 VxD 也不行,它只用于 Windows 95 ,在 Windows 98 中也可以用,但 Windows NT 和 windows 2000 都不支持。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表

圖片精選

主站蜘蛛池模板: 九九热在线视频观看 | 久久久久久久久久久国产精品 | 久久久久久久久久综合 | 姑娘第5集高清在线观看 | 久久精品无码一区二区三区 | 中文字幕免费在线观看视频 | 日本欧美一区二区三区在线观看 | 精品呦女 | 久久精品国产99久久久古代 | 久久精精品 | 精品一区免费 | 欧美在线成人影院 | 操碰网| 精品久久久久久国产 | 欧美一级精品片在线看 | 欧美亚洲综合在线 | 久久伊人国产精品 | 久久久久久久一区二区 | 欧美一级黄色片在线观看 | 手机av在线电影 | 国产一级一区 | 91网站在线观看视频 | 国产乱淫av一区二区三区 | 精品一区二区久久久久久按摩 | 黄色免费大片 | 亚洲看片网 | 欧美日韩在线视频观看 | 国产精品久久久久久久久久东京 | 成人短视频在线观看免费 | 深夜免费视频 | 欧美成人免费一区二区三区 | 99国产精成人午夜视频一区二区 | av电影在线观看网站 | 激情欧美在线 | 国产妇女乱码一区二区三区 | 久久网日本 | 久色伊人 | 久久精品小短片 | 天天草夜夜爽 | 自拍偷拍亚洲图片 | 姑娘第四集免费看视频 |