麻豆小视频在线观看_中文黄色一级片_久久久成人精品_成片免费观看视频大全_午夜精品久久久久久久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 都不支持。

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

圖片精選

主站蜘蛛池模板: 久久久鲁 | 久久亚洲线观看视频 | 国产午夜电影 | 毛片在线免费视频 | 特一级毛片 | 羞羞答答xxdd在线播放 | 精品人成| 成人在线视频精品 | japanesexxxx24videofree| 亚洲精品a在线观看 | 国产欧美精品一区二区三区四区 | 国产亚洲精品久久久久久久久久 | 国产1区2区在线 | 龙床上的呻吟高h | 亚洲人成中文字幕在线观看 | av色偷偷| 一级黄色毛片免费 | 午夜视频在线免费观看 | 成人nv在线观看 | 久久美女色视频 | 色欧美视频 | 55夜色66夜色国产精品视频 | 欧美一级在线免费 | 精品国产一区二区亚洲人成毛片 | 羞羞视频一区二区 | 国产乱淫a∨片免费观看 | 国内精品久久久久久久久久 | 久久不射电影网 | 欧美一区二区三区中文字幕 | 亚洲一区成人在线 | 97青青草视频 | 一级看片免费视频 | 美女黄网站免费观看 | 久久久久久久久久久久久久av | a视频网站 | 日日做夜夜操 | 久久久久久亚洲综合影院红桃 | 日韩色视频 | 久久久一区二区三区精品 | 精品一区二区久久久久 | 亚洲成人中文字幕在线 |