<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                合規國際互聯網加速 OSASE為企業客戶提供高速穩定SD-WAN國際加速解決方案。 廣告
                ### 1.代碼清單 ~~~ ;代碼清單9-1 ;文件名:c09_1.asm ;文件說明:用戶程序 ;創建日期:2011-4-16 22:03 ;=============================================================================== SECTION header vstart=0 ;定義用戶程序頭部段 program_length dd program_end ;程序總長度[0x00] ;用戶程序入口點 code_entry dw start ;偏移地址[0x04] dd section.code.start ;段地址[0x06] realloc_tbl_len dw (header_end-realloc_begin)/4 ;段重定位表項個數[0x0a] realloc_begin: ;段重定位表 code_segment dd section.code.start ;[0x0c] data_segment dd section.data.start ;[0x14] stack_segment dd section.stack.start ;[0x1c] header_end: ;=============================================================================== SECTION code align=16 vstart=0 ;定義代碼段(16字節對齊) new_int_0x70: push ax push bx push cx push dx push es .w0: mov al,0x0a ;阻斷NMI。當然,通常是不必要的 or al,0x80 out 0x70,al in al,0x71 ;讀寄存器A test al,0x80 ;測試第7位UIP jnz .w0 ;以上代碼對于更新周期結束中斷來說 ;是不必要的 xor al,al or al,0x80 out 0x70,al in al,0x71 ;讀RTC當前時間(秒) push ax mov al,2 or al,0x80 out 0x70,al in al,0x71 ;讀RTC當前時間(分) push ax mov al,4 or al,0x80 out 0x70,al in al,0x71 ;讀RTC當前時間(時) push ax mov al,0x0c ;寄存器C的索引。且開放NMI out 0x70,al in al,0x71 ;讀一下RTC的寄存器C,否則只發生一次中斷 ;此處不考慮鬧鐘和周期性中斷的情況 mov ax,0xb800 mov es,ax pop ax call bcd_to_ascii mov bx,12*160 + 36*2 ;從屏幕上的12行36列開始顯示 mov [es:bx],ah mov [es:bx+2],al ;顯示兩位小時數字 mov al,':' mov [es:bx+4],al ;顯示分隔符':' not byte [es:bx+5] ;反轉顯示屬性 pop ax call bcd_to_ascii mov [es:bx+6],ah mov [es:bx+8],al ;顯示兩位分鐘數字 mov al,':' mov [es:bx+10],al ;顯示分隔符':' not byte [es:bx+11] ;反轉顯示屬性 pop ax call bcd_to_ascii mov [es:bx+12],ah mov [es:bx+14],al ;顯示兩位小時數字 mov al,0x20 ;中斷結束命令EOI out 0xa0,al ;向從片發送 out 0x20,al ;向主片發送 pop es pop dx pop cx pop bx pop ax iret ;------------------------------------------------------------------------------- bcd_to_ascii: ;BCD碼轉ASCII ;輸入:AL=bcd碼 ;輸出:AX=ascii mov ah,al ;分拆成兩個數字 and al,0x0f ;僅保留低4位 add al,0x30 ;轉換成ASCII shr ah,4 ;邏輯右移4位 and ah,0x0f add ah,0x30 ret ;------------------------------------------------------------------------------- start: mov ax,[stack_segment] mov ss,ax mov sp,ss_pointer mov ax,[data_segment] mov ds,ax mov bx,init_msg ;顯示初始信息 call put_string mov bx,inst_msg ;顯示安裝信息 call put_string mov al,0x70 mov bl,4 mul bl ;計算0x70號中斷在IVT中的偏移 mov bx,ax cli ;防止改動期間發生新的0x70號中斷 push es mov ax,0x0000 mov es,ax mov word [es:bx],new_int_0x70 ;偏移地址。 mov word [es:bx+2],cs ;段地址 pop es mov al,0x0b ;RTC寄存器B or al,0x80 ;阻斷NMI out 0x70,al mov al,0x12 ;設置寄存器B,禁止周期性中斷,開放更 out 0x71,al ;新結束后中斷,BCD碼,24小時制 mov al,0x0c out 0x70,al in al,0x71 ;讀RTC寄存器C,復位未決的中斷狀態 in al,0xa1 ;讀8259從片的IMR寄存器 and al,0xfe ;清除bit 0(此位連接RTC) out 0xa1,al ;寫回此寄存器 sti ;重新開放中斷 mov bx,done_msg ;顯示安裝完成信息 call put_string mov bx,tips_msg ;顯示提示信息 call put_string mov cx,0xb800 mov ds,cx mov byte [12*160 + 33*2],'@' ;屏幕第12行,35列 .idle: hlt ;使CPU進入低功耗狀態,直到用中斷喚醒 not byte [12*160 + 33*2+1] ;反轉顯示屬性 jmp .idle ;------------------------------------------------------------------------------- put_string: ;顯示串(0結尾)。 ;輸入:DS:BX=串地址 mov cl,[bx] or cl,cl ;cl=0 ? jz .exit ;是的,返回主程序 call put_char inc bx ;下一個字符 jmp put_string .exit: ret ;------------------------------------------------------------------------------- put_char: ;顯示一個字符 ;輸入:cl=字符ascii push ax push bx push cx push dx push ds push es ;以下取當前光標位置 mov dx,0x3d4 mov al,0x0e out dx,al mov dx,0x3d5 in al,dx ;高8位 mov ah,al mov dx,0x3d4 mov al,0x0f out dx,al mov dx,0x3d5 in al,dx ;低8位 mov bx,ax ;BX=代表光標位置的16位數 cmp cl,0x0d ;回車符? jnz .put_0a ;不是。看看是不是換行等字符 mov ax,bx ; mov bl,80 div bl mul bl mov bx,ax jmp .set_cursor .put_0a: cmp cl,0x0a ;換行符? jnz .put_other ;不是,那就正常顯示字符 add bx,80 jmp .roll_screen .put_other: ;正常顯示字符 mov ax,0xb800 mov es,ax shl bx,1 mov [es:bx],cl ;以下將光標位置推進一個字符 shr bx,1 add bx,1 .roll_screen: cmp bx,2000 ;光標超出屏幕?滾屏 jl .set_cursor mov ax,0xb800 mov ds,ax mov es,ax cld mov si,0xa0 mov di,0x00 mov cx,1920 rep movsw mov bx,3840 ;清除屏幕最底一行 mov cx,80 .cls: mov word[es:bx],0x0720 add bx,2 loop .cls mov bx,1920 .set_cursor: mov dx,0x3d4 mov al,0x0e out dx,al mov dx,0x3d5 mov al,bh out dx,al mov dx,0x3d4 mov al,0x0f out dx,al mov dx,0x3d5 mov al,bl out dx,al pop es pop ds pop dx pop cx pop bx pop ax ret ;=============================================================================== SECTION data align=16 vstart=0 init_msg db 'Starting...',0x0d,0x0a,0 inst_msg db 'Installing a new interrupt 70H...',0 done_msg db 'Done.',0x0d,0x0a,0 tips_msg db 'Clock is now working.',0 ;=============================================================================== SECTION stack align=16 vstart=0 resb 256 ss_pointer: ;=============================================================================== SECTION program_trail program_end: ~~~ 以上就是全部的代碼了(加載器采用第八章的) 也不知道我這個插件怎么了,顯示出的源碼歪歪扭扭,沒有對齊![哭泣的臉](https://box.kancloud.cn/2016-02-29_56d3a8f857ea0.jpg) 好吧,咱們就湊合看吧。 ### 2.用戶程序結構圖 [![用戶程序結構圖_thumb[2]](https://box.kancloud.cn/2016-02-29_56d3a8f867755.jpg "用戶程序結構圖_thumb[2]")](http://img.blog.csdn.net/20160101232123711) ### 3.中斷處理程序 最開始的部分是頭部,嚴格遵循第八章作者約定的格式,我們就不多說了。 ~~~ ;=============================================================================== SECTION code align=16 vstart=0 ;定義代碼段(16字節對齊) new_int_0x70: push ax push bx push cx push dx push es ~~~ 這里就開始中斷處理程序了。首先是把用到的寄存器入棧,這是必須的。 ~~~ .w0: mov al,0x0a ;阻斷NMI。當然,通常是不必要的 or al,0x80 out 0x70,al in al,0x71 ;讀寄存器A test al,0x80 ;測試第7位UIP jnz .w0 ;以上代碼對于更新周期結束中斷來說 ;是不必要的 xor al,al or al,0x80 out 0x70,al in al,0x71 ;讀RTC當前時間(秒) push ax mov al,2 or al,0x80 out 0x70,al in al,0x71 ;讀RTC當前時間(分) push ax mov al,4 or al,0x80 out 0x70,al in al,0x71 ;讀RTC當前時間(時) push ax ~~~ 這段代碼要細說,有很多新知識。 ### (1)CMOS RAM 在外圍設備控制芯片(ICH)內部,集成了實時時鐘電路(RTC)和兩小塊由互補金屬氧化物(CMOS)材料組成的靜態存儲器(CMOS RAM)。實時時鐘電路負責計時,而日期和時間的數值則存儲在這塊存儲器中,它們由電腦主板上的一個小紐扣電池提供能量。 日期和時間信息存儲在CMOS RAM中,通常CMOS RAM有128個存儲單元,而日期和時間信息只占了一小部分容量,其余空間則保存整機的配置信息。 RTC芯片由一個頻率為32.768kHz的晶振驅動,經過分頻后,用于對CMOS RAM進行每秒一次的時間刷新。 表格9-1 CMOS RAM中的時間信息 <table border="0" cellspacing="0" cellpadding="2" width="400"><tbody><tr><td valign="top" width="100"><p align="center">偏移地址</p></td><td valign="top" width="100"><p align="center">內容</p></td><td valign="top" width="100"><p align="center">偏移地址</p></td><td valign="top" width="100"><p align="center">內容</p></td></tr><tr><td valign="top" width="100"><p align="center">0x00</p></td><td valign="top" width="100"><p align="center">秒</p></td><td valign="top" width="100"><p align="center">0x07</p></td><td valign="top" width="100"><p align="center">日</p></td></tr><tr><td valign="top" width="100"><p align="center">0x01</p></td><td valign="top" width="100"><p align="center">鬧鐘秒</p></td><td valign="top" width="100"><p align="center">0x08</p></td><td valign="top" width="100"><p align="center">月</p></td></tr><tr><td valign="top" width="100"><p align="center">0x02</p></td><td valign="top" width="100"><p align="center">分</p></td><td valign="top" width="100"><p align="center">0x09</p></td><td valign="top" width="100"><p align="center">年</p></td></tr><tr><td valign="top" width="100"><p align="center">0x03</p></td><td valign="top" width="100"><p align="center">鬧鐘分</p></td><td valign="top" width="100"><p align="center">0x0a</p></td><td valign="top" width="100"><p align="center">寄存器A</p></td></tr><tr><td valign="top" width="100"><p align="center">0x04</p></td><td valign="top" width="100"><p align="center">時</p></td><td valign="top" width="100"><p align="center">0x0b</p></td><td valign="top" width="100"><p align="center">寄存器B</p></td></tr><tr><td valign="top" width="100"><p align="center">0x05</p></td><td valign="top" width="100"><p align="center">鬧鐘時</p></td><td valign="top" width="100"><p align="center">0x0c</p></td><td valign="top" width="100"><p align="center">寄存器C</p></td></tr><tr><td valign="top" width="100"><p align="center">0x06</p></td><td valign="top" width="100"><p align="center">星期</p></td><td valign="top" width="100"><p align="center">0x0d</p></td><td valign="top" width="100"><p align="center">寄存器D</p></td></tr></tbody></table> CMOS RAM的訪問,需要兩個端口:0x70是索引端口,用來指定內存單元;0x71是數據端口,用來讀寫相應單元里的內容。 舉例: mov al,2 out 0x70,al ;指定內存單元為2 in al,0x71 ;讀RTC當前時間(分) 需要說明的是,從很早的時候開始,端口0x70的最高位是控制NMI中斷的開關,當它為0時,允許NMI中斷;為1時,阻斷所有的NMI信號。其他7個bit,實際上用來指定CMOS RAM單元的索引號。 作者為了簡化問題,所以在訪問RTC時,直接關閉NMI,訪問結束后,再打開NMI(不管它之前是不是打開的)。 查閱資料,有的朋友說“訪問CMOS RAM可能導致產生NMI,所以需要關閉NMI。” 還有一點要注意:CMOS RAM中保存的日期和時間,默認是8421 BCD編碼,也就是用0000~1001分別代表它所對應的十進制數。 ~~~ .w0: mov al,0x0a ;訪問寄存器A or al,0x80 ;阻斷NMI out 0x70,al in al,0x71 ;讀寄存器A test al,0x80 ;測試第7位UIP jnz .w0 ;以上代碼對于更新周期結束中斷來說是不必要的 ~~~ test al,0x80 ,這句是測試寄存器A的bit7 正如書上155頁所說: CMOS RAM中的時間和日期會由RTC周期性地更新,在此期間,用戶程序不應當訪問它們。 寄存器A的bit7為0時,表示更新周期至少在488us內不會啟動。換句話說,此時訪問時間信息是安全的。 寄存器A的bit7為1時,表示正處于更新周期或者馬上就要啟動。 可以看到,上面的代碼就是反復測試寄存器A的bit7,如果是0,可以向下執行。 ~~~ xor al,al or al,0x80 out 0x70,al in al,0x71 ;讀RTC當前時間(秒) push ax ~~~ 這段代碼很好理解,就是讀出秒,并且把結果壓棧(壓棧時為了之后顯示在屏幕上) ~~~ mov al,2 or al,0x80 out 0x70,al in al,0x71 ;讀RTC當前時間(分) push ax mov al,4 or al,0x80 out 0x70,al in al,0x71 ;讀RTC當前時間(時) push ax ~~~ 道理同上。 ~~~ mov al,0x0c ;寄存器C的索引。且開放NMI out 0x70,al in al,0x71 ;讀一下RTC的寄存器C,否則只發生一次中斷 ;此處不考慮鬧鐘和周期性中斷的情況 ~~~ 這里要說一下寄存器C,這個寄存器是只讀寄存器。可以通過讀取這個寄存器,知道中斷是否發生,如果發生,還可以知道中斷原因。 寄存器C是8位寄存器。 [3:0]:保留; [7]:中斷請求標志,周期性中斷/鬧鐘中斷/更新結束中斷,任何一種發生都會使這位置1; [6]:周期性中斷標志,置1則表示發生了周期性中斷 [5]:鬧鐘中斷標志,置1則表示發生了鬧鐘中斷 [4]:更新結束中斷標志,置1則表示發生了更新結束中斷 注意,對寄存器的讀操作將導致[7:4]清零。在中斷發生后,我們應該讀取這個寄存器,將其清零,否則同樣的中斷不再產生。 ### (2)把BCD碼轉換為ascii碼 前面的代碼中,把時分秒都讀取出來并且壓棧了。下一步的工作就是出棧,在屏幕上顯示。前文已經說過,CMOS RAM中保存的日期和時間,默認是8421 BCD編碼,所以我們可以利用一個過程,把BCD編碼轉換成與其對應的ascii碼。 ~~~ bcd_to_ascii: ;BCD碼轉ASCII ;輸入:AL=bcd碼 ;輸出:AX=ascii mov ah,al ;分拆成兩個數字 and al,0x0f ;僅保留低4位 add al,0x30 ;轉換成ASCII shr ah,4 ;邏輯右移4位 and ah,0x0f add ah,0x30 ret ~~~ 舉個例子來說吧,比如前面我們讀取了小時到AL中,比如是12時,那么al=00010010b;前文我們壓棧是把AX壓進去,也就是說AX的低8位(AL)是有用的。現在我們需要調用這個過程,把00010010b轉換成0x3132(因為字符‘1’對應的ASCII碼是0x31,字符‘2’對應的ASCII碼是0x32)。 mov ah,al ;分拆成兩個數字 and al,0x0f ;僅保留低4位(就是個位) add al,0x30 ;把個位轉換成ASCII shr ah,4 ;邏輯右移4位 ,ah中是十位數字 and ah,0x0f add ah,0x30 ;把十位轉換成ASCII OK,這樣之后,AX的高八位就是十位的ASCII,低八位就是個位的ASCII; ### (3)把時間信息顯示在屏幕上 ~~~ mov ax,0xb800 mov es,ax pop ax call bcd_to_ascii mov bx,12*160 + 36*2 ;從屏幕上的12行36列開始顯示 mov [es:bx],ah mov [es:bx+2],al ;顯示兩位小時數字 mov al,':' mov [es:bx+4],al ;顯示分隔符':' not byte [es:bx+5] ;反轉顯示屬性 ~~~ 前兩句讓es指向了顯示緩沖區; pop ax ;小時出棧 call bcd_to_ascii ;轉為ASCII碼 mov bx,12*160 + 36*2 ;從屏幕上的12行36列開始顯示 mov [es:bx],ah ;顯示小時的十位 mov [es:bx+2],al ;顯示小時的個位 mov al,':' mov [es:bx+4],al ;顯示分隔符':' not byte [es:bx+5] ;反轉顯示屬性 其實前兩句可以寫成 mov [es:bx+4],':’ ;顯示分隔符':' not是按位取反指令,假如之前屬性是0x07(黑底白字),那么Not之后就是0xf8(閃爍白底灰色字)。 ~~~ pop ax call bcd_to_ascii mov [es:bx+6],ah mov [es:bx+8],al ;顯示兩位分鐘數字 mov al,':' mov [es:bx+10],al ;顯示分隔符':' not byte [es:bx+11] ;反轉顯示屬性 pop ax call bcd_to_ascii mov [es:bx+12],ah mov [es:bx+14],al ;顯示兩位小時數字 ~~~ 上面的代碼同理。 ~~~ mov al,0x20 ;中斷結束命令EOI out 0xa0,al ;向從片發送 out 0x20,al ;向主片發送 ~~~ 書上162頁已經說明:在中斷處理過程的結尾,我們要顯式地向8259芯片寫中斷結束命令EOI(至于具體原因,可以參考361頁,圖17-17:8259A的初始化命令字)。如果外部中斷是8259主片處理的,那么僅發送給主片即可,端口號是0x20;如果外部中斷是由從片處理的,那么命令既要發給主片也要發給從片,端口號是0xa0. 中斷結束命令的代碼是0x20. ~~~ pop es pop dx pop cx pop bx pop ax iret ~~~ 寄存器出棧,用iret命令返回。 ### 4.主程序 ### (1)初始化 ~~~ start: mov ax,[stack_segment] mov ss,ax mov sp,ss_pointer mov ax,[data_segment] mov ds,ax mov bx,init_msg ;顯示初始信息 call put_string mov bx,inst_msg ;顯示安裝信息 call put_string ~~~ 這就是程序的入口了。首先,設置棧段,棧段被安排在整個程序的末尾,保留了256字節。 ~~~ SECTION stack align=16 vstart=0 resb 256 ss_pointer: ;=============================================================================== SECTION program_trail program_end: ~~~ 之后,設置好DS,令其指向數據段;然后顯示一些信息。 ### (2)中斷初始化和安裝 [![70dd1691gac5bc07f4bdf&690_thumb[3]](https://box.kancloud.cn/2016-02-29_56d3a8f8790f1.jpg "70dd1691gac5bc07f4bdf&690_thumb[3]")](http://img.blog.csdn.net/20160101232125420) 書上158頁說:在計算機啟動期間,BIOS會初始化中斷控制器,將主片的中斷號設為從0x08開始,從片的從0x70開始。從上圖可以看出來,實時時鐘連到了從片的IR0,也就是說實時時鐘的中斷號是0x70. ~~~ mov al,0x70 mov bl,4 mul bl ;計算0x70號中斷在IVT中的偏移 mov bx,ax cli ;防止改動期間發生新的0x70號中斷 ~~~ 前文已經說過: **中斷向量在中斷向量表中的位置=中斷類型號×4** **N*4的字單元存放偏移地址;** **N*4+2的字單元存放段基址。** 我們已經知道中斷類型號是0x70了,下面要計算它在中斷向量表中的位置(也就是計算0x70*4):用乘法指令, AX=AL*r8; 前四句執行后,BX中就是0x70號中斷向量在向量表中的偏移。 cli這個指令用來清除IF位標志,相當于屏蔽外部中斷。因為在修改中斷向量表時,如果表項信息只修改了一部分,這時候發生0x70號中斷,將會產生不可預料的問題。 ~~~ push es mov ax,0x0000 mov es,ax mov word [es:bx],new_int_0x70 ;偏移地址。 mov word [es:bx+2],cs ;段地址 pop es ~~~ 將ES壓棧(暫時保存),并使它指向中斷向量表所在的段,把偏移地址設置為new_int_0x70 ,把段基地址設置為CS。最后恢復ES。 ~~~ mov al,0x0b ;RTC寄存器B or al,0x80 ;阻斷NMI out 0x70,al mov al,0x12 ;設置寄存器B,禁止周期性中斷,開放更 out 0x71,al ;新結束后中斷,BCD碼,24小時制 ~~~ 上面的代碼用來設置寄存器B;寄存器B與本實驗相關的位有: [7]: 0表示更新周期每秒都會發生;1表示中止當前的更新周期,此后也不再產生更新周期; [6]: 0表示禁止周期性中斷,1表示允許周期性中斷; [5]: 0表示鬧鐘中斷禁止,1表示鬧鐘中斷允許; [4]: 0表示禁止更新結束中斷,1表示允許更新結束中斷; [3]:該位空著不用; [2]:數據模式,0表示BCD,1表示2進制; [1]: 小時格式,0表示12小時制(bit7為0時表示AM,為1表示PM,舉例:在BCD模式下,10010001b表示上午11點),1表示24小時制; [0]:該位空著不用; 從代碼可以看出,我們寫入寄存器B的值是0x12,也就是: [7]:0,允許更新周期發生; [6]:0,禁止周期性中斷; [5]:0,禁止鬧鐘中斷; [4]:1,允許更新結束中斷; [3]:0 [2]:0,BCD模式 [1]:1,24小時制 [0]:0 ~~~ mov al,0x0c out 0x70,al in al,0x71 ;讀RTC寄存器C,復位未決的中斷狀態 ~~~ 讀寄存器C, 使之開始產生中斷信號。注意,在向端口0x70寫入al的同時,也打開了NMI,因為這是最后一次在主程序中訪問RTC。到此,RTC芯片設置完畢。 ~~~ in al,0xa1 ;讀8259從片的IMR寄存器 and al,0xfe ;清除bit 0(此位連接RTC) out 0xa1,al ;寫回此寄存器 sti ;重新開放中斷 ~~~ ? 8259A內部有一個中斷屏蔽寄存器,如下圖所示: [![8259A內部結構](https://box.kancloud.cn/2016-02-29_56d3a8f88f624.jpg "8259A內部結構")](http://img.blog.csdn.net/20160101232127631) ? IMR是一個8位的寄存器,位0-7對應著引腳中斷IR0-IR7;如果對應的位為0,則允許中斷;為1,則屏蔽中斷。 我們通過端口0xa1讀取從片的IMR寄存器,用and指令清除bit0(其他位保持原樣),然后再寫回去。這樣,關于中斷的初始化就完成了。 最后,sti指令將IF置1,打開中斷。從這時候開始,隨時發生的中斷就可以被處理了。 ~~~ mov bx,done_msg ;顯示安裝完成信息 call put_string mov bx,tips_msg ;顯示提示信息 call put_string ~~~ 顯示一些信息,表示中斷設置和安裝已完成。 ? ~~~ mov cx,0xb800 mov ds,cx mov byte [12*160 + 33*2],'@' ;屏幕第12行,33列 ~~~ 在屏幕12行33列顯示一個“@”; ~~~ .idle: hlt ;使CPU進入低功耗狀態,直到用中斷喚醒 not byte [12*160 + 33*2+1] ;反轉顯示屬性 jmp .idle ~~~ hlt是停機指令,使程序停止運行。這時候處理器進入暫停狀態,不執行任何操作。當復位線上有復位信號、CPU響應非屏蔽中斷、CPU響應可屏蔽中斷3種情況之一發生時,CPU就會脫離暫停狀態,執行hlt的下一條指令。 ? 代碼分析就到這里吧,下次我們看一下運行結果。![眨眼](https://box.kancloud.cn/2016-02-29_56d3a8f8abd34.jpg)
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看