標籤

2009年4月29日 星期三

Easy DOS command

http://www.slime.com.tw/teach/neto/teach/dos.htm

Easy DOS command
前言: 剛開始接觸電腦的人, 因為 Windows 的好用, 會讓人覺得學習電腦實在很容易, 可是如果要到 DOS 執行的指令, 總是令人感到蠻害怕的, 畢竟 DOS 給人的感覺沒有 Windows 來的親切嘛! 但是站長要跟你說喔! DOS 的指令其實也只有那麼一丁點 , 只要這點小指令你學起來了, 管它是 DOS 還是 Windows , 都是通行無阻的喔! 從此之後 , 保證 DOS 不再讓你害怕了, 讓我來教教你這些簡單的指令吧!
( 雖然 MS 的新產品將不再支援 DOS 系統 , 不過 MS 的 NT 裡也是有類似 DOS 的工具存在 , 所以這些指令對初學者也不會完全沒用。)
DOS 2000 年危機 :
1. 在 DOS 下 DIR 列出的檔案為什麼日期顯示為 00 呢 ? 別擔心 , 只要加上 /4 參數就可以將日期正常顯示為 2000 了 ,
ex. dir/4如果您嫌每次 DIR 都要加上 /4 參數粉麻煩的話 , 您也可以在 C:\Config.sys 裡增加這一行 set dircmd=/4 , 你可以用筆記本來開啟Config.sys 這個檔案 , 等修改好了存檔完畢之後重新開機就可以啦! 以後 DOS 下顯示的日期就是 2000 了。

 
1.DIR: 如果你在某個目錄下, 這個所謂的目錄可以是磁碟機, 也可以是資料夾, 譬如 C:\ 好了, 那你想看看 C: 槽究竟放了哪些資料呢? 很簡單喔! 你只要在 C:\ 的後面打上 DIR 就好了, 是不是粉簡單呢? 還有喔! 如果你覺得: 打個 DIR 在按 Enter 之後, 那個檔案咻就跑到最下面去了, 根本都沒看清楚就給它跑走了, 站長跟你說, 沒關係的, 我們不要跟它計較跑的那麼快, 否則有損身為人的自尊哦! 只要在打 DIR/P ,YA! 它每次都只會出現一頁的部分, 等我們看清楚了在按 Enter 看下一頁不就好啦! OK! 還有一個秘密喔! 就是如果你打 DIR/W 的話, 它只會顯示檔案名稱, 不會顯示一堆日期, 檔案大小, ...一堆有的沒有的。
2.FORMAT: 這個指令的用途就是格式化, 你應該知道格式化是什麼吧! 就是可以消滅磁碟中的病毒, 資料,裡面所有的東西, 很可怕喔! 不小心資料都會毀了, 但是磁片或是硬碟在剛買來都是要格式化過的, (現在買到的磁片大多數好像都已經格式化過了 ) ,其實如果磁片壞軌了, 也可以重新格式化, 有時候就好了說, 言歸正傳, 如果我們要格式化 A 槽, 只要打 FORMAT A: 就可以了, 格式化 C 槽就打入 FORMAT C: 就可以了。
3.COPY: 這個指令一看也知道是複製檔案用的嘛! 如果我們要將 A: 中的 lmi.txt 這個檔案複製到 C: 則可以打
COPY A: lmi.txt C:

如果我們要把 lmi.txt 從 A: 複製到 C: 而且要把複製的檔案名稱更為 hsuyin.txt 的話, 我們可以這樣作

COPY A: lmi.txt C: hsuyin.txt

最後還有一個絕招要跟你介紹, 如果你想要複製 A: 中所有的 .EXE檔到 C: ,我們就可以打
COPY A: *.EXE C: 就可以了。

4.DISCOPY: 這跟 COPY 很像, 但不太一樣, 如果你要把 A: 磁片內容整個複製到 B: 你可以打 DISCOPY A: B:
5. XCOPY : 這個指令可以用來複製整個目錄 , 譬如我要將 d:\HSUYIN 這個目錄裡的檔案全部複製到 d:\LMI 裡面 , 只要打入 xcopy d:\HSUYIN d:\LMI 就可以啦 。
6.DEL: 這個指令可以刪除檔案的, 如果說你的電腦中了病毒, 或者你想要刪除一些檔案, 可是在 Windows 系統中它總是告訴你 "Windows 正在使用檔案, 因此無法刪除", 那就是要到 DOS 刪除了, 假設我要刪除 lmi.txt 我只要打 DEL lmi.txt 就可以了, 那如果你要刪除資料夾中所有檔案只要打 DEL *.* 就可以啦。
7.REN: 這是將檔案重新命名, 例如我要將 LMI.TXT 改成 HSUYIN.TXT 就可以打 REN LMI.TXT HSUYIN.TXT 當然, 如果你要更改所有的副檔名, 你也可以打 REN *.TXT *.DOC ,清楚這指令的意思嗎? 這是說我把這個資料夾中所有的 .txt 改成 .doc 檔。
8.MD: 這個指令可以建立一個新的資料夾, 如果我要建立一個 hsuyin 的資料夾我就可以打入 MD hsuyin 或是打 MKDIR hsuyin 也是可以的。
9.RD: 這個指令跟 MD 恰好相反, 可以刪除一個空的資料夾, 一定要是空的才有辦法刪除喔! 用法是這樣子的, 假設我要刪除 hsuyin 就可以打 RD hsuyin 或是打 RMDIR hsuyin
10. DELTREE: 這是比 RD 還要強的刪除資料夾指令, 因為如果要刪除一個資料夾 RD 就要先刪除裡頭所有的資料夾跟檔案, 而 DELTREE 可以連資料夾裡面的資料夾或是檔案一起刪除, DELTREE 就跟 Windows 中的刪除資料夾一樣把整個資料夾給刪除了, 我要刪除 hsuyin 這個資料夾就可以打 DELTREE hsuyin 就可以啦, 是不是粉簡單呢 ?
11.TYPE: 這個指令是給我們列印文字檔用的, 假設我要印 LMI.txt 的內容就打 TYPE LMI.txt 就可以了。
12.CLS: 用來清除螢幕。
13. 尋找檔案 : 在 DOS 裡尋找檔案也蠻方便的喔 ! 如果你要在 C:\ 找一個檔名為 XXX.txt 的檔案你可以打 dir /s XXX.txt 這樣就可以搜尋出所有 c:\ 中的 XXX.txt
14. cd: 在 Windows 中我們要進入一個資料夾只要用滑鼠左鍵點兩下就好啦 ! 在 DOS 中要進入資料夾就是打 CD 了, 現在假設現在我停留在 c:\ 裡 , 我要進入 C:\ 中的 Windows 資料夾 , 我只要打 cd Windows 就可以了, 如果你現在是在 A: ,你只要打 C: 就可以進入 C: 了, 那要怎麼離開資料夾呢? 如果我是在 C:\Windows\Desktop 而我要退回到 C:\Windows 我只要打 cd.. 就可以了。
15. 離開 dos : 若您開啟的是 windows 下的 dos , 那麼要離開 dos 程式只要鍵入 EXIT 就可以囉!
最後我在說明一下這些符號 ( 萬用字元 ) 的意思: 就是 * ? ( * 是用來當作任意一行字 ? 則是用來當作任意一個字來用), 就像我們之前說的, 我要複製所有的 .txt 檔到 A: 我們可以打 COPY *.txt A: 我們要刪除所有檔案可以打 DEL *.* ( * 就像是一個數學中的變數 X 在這裡我們讓 * 代表了任意一行字, *.txt 就是所有的 .txt 檔, 不管它叫作 lmi.txt 或是hsuyin.txt 或是 123.txt 或是 abcd.txt 都可以 , *.txt 中的 * 取代了 .txt 之前的那串字, 所以不管是 lmi 或是 hsuyin 或是 123 或是 abcd 都可以用 * 來表示, 這樣對 * 的意思你們應該已經瞭解了吧!嗯! 接下來說 ? 的意思, 其實 * 只要懂了, ? 的意思也不難, 因為 * 是代表一串字, 而 ? 是代表一個字, 喔! 知道了吧! 你看看喔! DEL ???.txt 是什麼意思, 我們是要刪除所有在 .txt 前面是三個字的檔案, 以前面的例子來說, lmi.txt123.txt 會被刪除, 而 hsuyin.txt 和 abcd.txt 因為 hsuyin abcd 不是 3 個字元嘛! 所以不會被刪除, 蠻好玩的喔!
其他指令: ( 可以不用看 , 不過您可以試試看 , 蠻有趣的 )
1. date : 更改系統日期
2. time : 更改系統時間
3. ver : 查詢您系統的版本
4. edit : DOS 下的文書編輯程式 。
5. more : type 一樣功能 , 不過有自動分頁
6. move : 移動檔案 , 用法與 copy 類似
7." > " : 改變輸出 , 譬如 dir > 1.txt 將會把 dir 出來的內容傳到 1.txt 這個文字檔案裡面 ( 1.txt 可命名為任意文字檔名 , 1.txt 可為已存在檔案或是不存在的檔案 , 若為不存在檔案 , 系統會自動建立。 )
8. 指令參數使用說明 : 以上的 dos 指令都有更多詳細的參數使用說明 , 您可以在指令後加上 /? 就可以查詢此只應的參數了 , 比如我要查詢 dir 的用法只要在 dos 中鍵入 dir/? 即可。
9. attrib 在 DOS 底下更改檔案屬性 : 比如我要將 readme.txt 屬性改成隱藏檔 , 可以打 attrib +h readme.txt , 那如果要取消檔案隱藏的屬性 , 只要將 + 改成 - 號就可以了 ex. attrib -h readme.txt , 更多的參數設定請在 DOS 底下打入 attrib /? 查詢。
如果對更多 DOS 的指令有興趣 , 您可以查詢關於 DOS 的書籍。
 
 
以上資料僅供參考
lmi 撰寫

2009年4月27日 星期一

ACPI C state

http://baike.baidu.com/view/2051969.html?tp=2_01



  ACPI Processor C-state
  在G0工作狀態下,ACPI會定義系統處理器的電源狀態為活躍狀態(正在執行)或是睡眠狀態(未執行)。處理器電源狀態被設計為C0,C1,C2,C3...Cn。C0電源狀態是活躍狀態,即CPU執行指令。C1到Cn都是處理器睡眠狀 態,即和C0狀態相比,處理器處理器消耗更少的能源並且釋放更少的熱量。當進入睡眠狀態,處理器不執行任何指令。每個睡眠狀態都有一個和省電多少對應的延遲。一般來說,進入和退出的延遲越長,這個狀態越省電。為了保持能量,OSPM在空閒時將處理器置於其中一個支援的睡眠狀態中。
  在C0狀態下,ACPI允許處理器的性能透過一個定義的節制過程發生改變,透過改變進入多種性能狀態(P-states)改變處理器的電源狀態。
  ACPI定義這樣的邏輯在每個CPU的配置,即OSPM通過轉換來切換不同的處理器電源狀 態。這個邏輯是可選擇的,在FADT表和處理器對象中有描述。FADT表中的這些字段和標誌描述了硬件的對稱性,以及處理器對象對特別的CPU時鐘邏輯包含的位置(在P_BLK寄存器塊和_CST中有描述)。
  P_LVL2和P_LVL3寄存器提供可選擇的支援,將系統處理器置於C2或者C3狀態。 P_LVL2寄存器將排序好的處理器置於C2狀態,P_LVL3講排序好的處理器置於C3狀態。C3狀態的額外支持通過總線主狀態和仲裁禁止位被提供 (PM!1_STS寄存器中的BM_STS位和PM2_CNT寄存器中的ARB_DIS位)。系統軟件通過讀取P_LVL2或者P_LVL3寄存器數據來 進入C2或者C3狀態。硬件必須精確的將處理器放在恰當的時鐘狀態,通過對相應的P_LVLx寄存器的讀操作。平台必須定義可選的接口來允許OSPM使用 _CST對象進入C-state。
  透過FADT表和P_BLK接口,處理器的電源狀態支援是對稱的;OSPM假設同一系統裡的所 有的處理器都在相同的電源狀態下。如果處理器有不對稱的電源狀態支持,BIOS將通過FADT表選擇和使用所有處理器最低的相同的電源狀態。例如,如果 CPU0支持所有的電源狀態乃至C3,但是CPU1僅支持C1,那麼OSPM將僅將空閒的處理器置於C1(CPU0將不會被置於C2和C3狀態)。注意 C1必須被支持,C2和C3是可選的。

  處理器電源狀態C1
  所有的處理器必須支援這種狀態。這種狀態的支援是透過一個本地的處理器指令(HLT或者 mwait),並且認為不需要晶片組的硬件支持。這種狀態的硬體延遲必須夠低,使得OSPM在決定是否使用該狀態時不需要考慮延遲方面的問題。除了將 處理器置於一種電源狀態,這個狀態沒有其他的軟件可見的效果。在C1狀態下,處理器可以保持系統cache裡面的內容
  硬件可以以任何理由退出該狀態,但必須是在有中斷到達處理器的情況下。

  處理器電源狀態C2
  這種電源狀態不是必須的。如果存在,省電效果更好,它通過使用P_LVL2命令寄存器 或者由_CST提供的另一種機制來使處理器進入該狀態。這個狀態的最壞情況下的硬體延遲在FADT的表裡面有聲明,OSPM可以根據這個信息來決定什麼時候C1狀態應該被C2狀態代替。除了將處理器置於一種電源狀態,該狀態沒有其他的軟件可見效果。OSPM假設C2比C1更省電,但是退出的延遲比C1要 高。
  C2電源狀態是一種可選的ACPI時鐘狀態,需要晶片的硬件支持。時鐘邏輯由一個接口組成,可以用來被操縱使處理器精確的進入C2電源狀態。在C2電源狀態下,處理器被認為能夠保持其cache的一致性;例如,總線控制器和多處理器的活動可以發生而不破壞cache裡面的內容。
  C2狀態將處理器置於一種低功耗的狀態,圍繞多處理器和總線控制器系統做優化。當存在總線控制器或者多處理器活動時(這一條件將阻止處理器進入C3狀態),OSPM將使一個空閒狀態下的處理器群體進入C2狀態。處理器簇能夠在C2狀態下監視總線控制器或者多核CPU訪問的行為。
  硬件可以以任何理由退出該狀態,但必須是在有中斷到達處理器的情況下。

  處理器電源狀態C3
  系統對C3處理器電源狀態的支援也是可選擇的. 如果存在,這種狀態比C1和C2狀態更加節省功耗。使用P_LVL3命令寄存器或者_CST機制可以進入C3狀態,這種狀態的最壞的硬體延遲在FADT表中聲明了,OSPM可以通過這一信息來決定什麼時候需要進入C3狀態而不是C1或者C2狀態。當在C3狀態中,處理器的cache保持狀態,但是處理器沒有窺視總線控制器,或者多核CPU進行訪存。
  硬件可以以任何理由退出這種狀態,但必須是因為一個中斷投遞到了該處理器,或者當BM_RLD被設置時,一個總線控制器企圖訪存.
  OSPM負責保證cache的一致性.在單處理器環境下,這可以通過使用 PM2_CNT.ARB_DIS總線控制器仲裁寄存器來保證總線控制器的活動不會發生在C3狀態下. 在多處理器環境下,處理器的cache可以通過flush和invalidate來保持一致性.
  有兩種機制支持C3電源狀態:
  1. 在進入C3狀態之前,讓OSPM flush和invalidate cache
  2. 提供一種硬件機制,阻止控制器寫內存(只支持UP)
  在第一種情況下,OSPM將在進入C3之前flush系統的cache,由於flush系統的cache通常有很大的延遲,OSPM只對多核平台的空閒處理器支持這種情況。flush cache通過ACPI定義的一種機制來完成。
  單處理器平台提供一種硬件功能,OSPM將嘗試將平台置於一種模式,當處理器處於C3模式,這種模式組織系統總線控制器來寫內存。一旦總線控制器請求一個訪問,CPU將從C3中被喚醒,並且重新使能總線控制器訪問。
  OSPM使用BM_STS來決定要進入的電源狀態是C2還是C3.,BM_STS是一個可選的bit,表示總線控制器是活躍的。OSPM使用這一位來決定在C2和C3之間的策略。頻繁的總線控制器活動將CPU的電源狀態降到C2,沒有總線控制器活動將CPU的電源狀態提升到C3。OSPM保持BM_STS的一個變化歷史來決定CPU電源狀態的策略.
  用在C3里的最後一個硬體特性是BM_RLD位元. 這一位元決定總線控制器的訪問是否導致Cx電源狀態的退出,如果這一位元被設置,一旦有總線控制器訪問,Cx將退出。如果該位被覆位為零,總線控制器的訪問將不會導致電源狀態的退出。在C3狀態中,總線控制器的申請需要CPU轉換回C0狀態,但是在C2狀態中,這樣的轉換將不是必須的。在C3狀態下,OSPM可以設置這一位,在C1或C2狀態下,可以清除該位。

2009年4月21日 星期二

BIOS boot spec

http://www.wretch.cc/blog/hyper0672/9867131


以下為轉帖

完整的文件可以參考
http://www.phoenix.com/NR/rdonlyres/56E38DE2-3E6F-4743-835F-B4A53726ABED/0/specsbbs101.pdf
以下為一些重點整理

BBS (BIOS Boot Specification) 是用來規範 BIOS 如何選擇啟動裝置。它包含了
1. 辨識系統中的 IPL (Initial Program Load) 裝置
2. 根據使用者的選擇,尋訪每個裝置並檢視它是否能夠啟動系統

IPL (Initial Program Load) Device:
IPL Devie 指的是可以啟動載入並執行作業系統的裝置。他包含了像是 Floppy, Hard drives, CD-ROM, PCMCIA conrtollers/cards, PnP Cards, Legacy cards 甚至像是 Network, Serial port, Parallel port 等等可開機的實體或虛擬裝置。
所有的 IPL 可以被歸類成下列三種
1. BAID
2. PnP Card (可再細分為 BCV 和 BEV 兩種裝置)
3. Legacy IPL Device

BAID (BIOS Aware IPL Device):
此類 IPL 需要 BIOS 的程式碼支援,來提供它啟動系統的能力。通常啟動的程式碼內建於 INT 19h (BIOS Bootstrap loader) 的服務之中。常見的裝置如下:
First floppy drive, First ATA Hard drive, PCI ATA card drive, ATAPI CD-ROM drive, PCMCIA controller bootable card, Ethernet controller code embedded in BIOS

PnP Cards:
此類 IPL 裝置,必須附加 option ROM 於 C0000h-EFFFFh (2K boundary)。而且在 Option ROM 中必須有 PnP Option ROM Header (Table 2)。另外,開機相關資訊會被記錄在 PnP Expansion Header (Table 3),在此表格中,包含了 BCV 或 BEV 的指標。

BCV (Boot Connection Vector):
BCV 是一個指標,指向 Option ROM 中的某一段程式碼。這段程式碼負責執行裝置的初始化、偵測硬體 (例如是否有 SCSI 裝置連接到系統) 或者在必要時 Hook INT 13h 的服務 (Disk I/O)。常見的有:
PnP SCSI card drive, NoN-PnP card PnP Expansion Header

BEV (Bootstrap Entry Vector):
BEV 是一個指標,指向 Option ROM 中負責載入作業系統的一段程式碼,並在必要時 Hook INT 18h 或 INT 19h 的服務。通常於網路卡裝置的 Network Remote Boot 時使用。常見的有:
PnP Token Ring card, PnP Ethernet card, NoN-PnP card PnP Expansion Header

Legacy IPL Devices:
此類裝置為標準的 ISA Card,其包含了一個 Option ROM 於 C0000h-EFFFFh (2K boundary)。此類型的裝置於 Option ROM 並沒有 PnP Expansion Header 的相關資訊。在它的 Option ROM 被 BIOS 找到時,會先執行一段初始化的程式。這段程式執行期間,會根據需要來 Hook INT 19h, INT 18h 以及 INT 13h。

IPL Table
每個 BAID 以及 BEV 裝置必須在 IPL Table 中有一個相對應的欄位
範例
0: Floppy A:
1: Hard Drive C:
2: CD-ROM
3: BEV #1
4: BEV #2

IPL Priority
IPL Priority 決定 IPL 開機的順序。它存在於非揮發性記憶體中,並且可以讓使用者修改。在 INT 19h (載入作業系統) 呼叫中,它必須能夠被取用,並且根據表格中的順序來進行開機的程序。
範例
0: 3 (BEV #1)
1: 4 (BEV #2)
2: 1 (Hard Drive C:)
3: 2 (CD-ROM)
4: 0 (Floppy A:)

IPL Priority Pseudocode
Created at BIOS build time:
First few IPL Table entries are filled in by the BAIDs.
maxIPLCount = Number of entries in IPL Table.
baidCount = Number of BAIDs in the system.
maxBEVCount = (maxIPLCount - baidCount).
The NV memory space for the IPL Priority is reserved.
Assumptions:
· The default for the IPL Priority will automatically be
created during POST in case the NV memory gets corrupted.
· nvBEVCount = number of BEV devices found last time -
stored in NV memory.
· postBEVCount = number of BEV devices found this time.
Execution at POST time:
· All option ROMs with a PnP Expansion Header are identified
and their initialization entry points are called.
· Additional IPL Table entries are filled in with the BEV
devices found.
· IF (NV memory is corrupted)
· Set default IPL Priority by first placing the BAIDs,
and then adding in the BEVs in the order they were found.
· ELSE
· The IPL Priority is retrieved from NV memory.
· deltaBEVCount = (nvBEVCount - postBEVCount).
· IF (deltaBEVCount != 0)
· IF (deltaBEVCount > 0)
· FOR (i = 0; i != deltaBEVCount; ++i)
· Add a new BEV device to the end of IPL Priority.
· ELSE
· For (i = 0; i != deltaBEVCount; --i)
· Delete the BEV device nearest the end of IPL Priority.
· ENDIF
· Save the postBEVCount in NV memory as nvBEVCount.
· Save the new IPL Priority in NV memory.
· (Optional) - Display a message that the IPL Priority
changed and allow the user to enter Setup to reconfigure
the IPL Priority.
· ENDIF
· ENDIF
· Invoke INT 19h.

BCV Priority
在 BIOS INT 13h (Disk I/O) 的服務之中,磁碟機代號 00-7Fh 為 Floppy Disk, 而 80-FFh 為 Fixed Disk。而這些代號和實體磁碟的對應必須在 BIOS 中完成。另外值得注意的一點就是,由於只有第一台 Floppy 和第一台 Fixed Disk 可以用來啟動 (代號 00h 以及 80h),所以根據不同的啟動設定,也必須將 INT 13h Hook 的順序作調整才能夠順利開機。
舉例來說,如果 ATA 硬碟佔用掉 80h,而 SCSI 只能佔用 81h 之後的磁碟機代號的話,那麼 SCSI 硬碟就不能作為開機的硬碟了。

範例
BCV Table
0: ATA Drives
1: Legacy Cards
2: BCV #1
3: BCV #2

BCV Priority
0: 2 (BCV #1)
1: 0 (ATA Drives)
2: 1 (Legacy Cards)
3: 3 (BCV #2)

INT 13h 支援的裝置有下列幾種
1. ATA Drive
2. PnP Cards with BCVs
3. Legacy Cards with Option ROMs
4. Hard Drive BAID

關於 INT 13h 的幾個重點
1. 當 INT 13h 被 Hook 時,舊的 INT 13h Vector 必須被保存
2. 已經安裝的硬碟數目必須被保存在 BDA 0040:0075
3. 第一個安裝的硬碟會得到 80h 的代號,這也代表著它是開機硬碟
4. 一旦安裝到 INT 13h 之後,就不能被解除安裝

BCV Post Pseudocode


Created at BIOS build time:
· First two BCV Table entries are filled in by ATA support and
Legacy option ROM
support.
· The NV memory space for the IPL Priority is reserved.
Assumptions:
· The default for the BCV Priority will automatically be
created during POST in case the NV memory gets corrupted.
1. Call the video option ROM.
2. Initialize the first two BCV Table entries with ATA Support
and Legacy Cards respectively. These two entries will always
exist in the BCV Table and will always be in that order.
3. Identify all option ROMs with BCVs and add any that are
found to the BCV Table.
4. Call all the BCV option ROMs in the order they reside in
the BCV Table and store their return value in AX upon return.
5. If NV memory is corrupted, set defaults for BCV Priority
and BCVCount.
6. Check if the number of BCV devices found this time matches
the number found last time. If not, update the BCV Priority
and BCVCount accordingly.
7. FOR (i = 0; i < index =" BCV">

INT 19h
在這個服務呼叫時,所有的 IPL 已經被辨識,並且 INT 13h 的裝置也都已安裝完成。在呼叫之後,它會根據 IPL Priority 中的裝置,呼叫其 Boot handler。第一個呼叫成功的裝置會負責載入作業系統。如果全部的裝置都已呼叫過後還沒有成功載入作業系統,它會顯示一個錯誤訊息,並且等待重新開 始。
以下為 INT 19h 的 Pseudocode
· IPLcount = current number of BAIDs and BEV devices at this boot.
· FOR (i = 0; i < currentipl =" IPL">

INT 18h
原本的 INT 18h 的動作是將控制權交給 BIOS,顯示一個錯誤訊息並且等待使用者按下按鍵後進行下一個動作。而在 BBS 中重新定義 INT 18h 的功能為錯誤回覆的中斷向量。這裡要注意的是 INT 18h 並不會返回至呼叫它的程序,並且在一開始就將堆疊重新設定。
以下為 INT 18h 的 Pseudocode
· Reset stack.
· IF (all IPL devices have been attempted)
· Print an error message that no O/S was found.
· Wait for a key stroke.
· Execute the INT 19h instruction.
· ELSE
· Determine which IPL device failed to boot.
· Jump to a label in the INT 19h handler to try the next
IPL device.
· ENDIF

Boot Menu (Optional)
在 POST 期間,部份 BIOS 充許使用者使用一個特定的 Hot Key 來呼叫 Boot Menu,並用它來改變 INT 19h 所使用的啟動裝置。這裡要注意的是,這個動作並不會改變 IPL Priority 的內容,它只是單純地選擇啟動的裝置。
以下為 Pseudocode
IF (A Boot Menu selection was made)
currentIPL = IPL Priority[Boot Menu selection].
Use currentIPL to select the BAID or BEV table entry.
Do a far call to the boot handler, if successful we never return.
IF (we get control back via RETF, or an INT 18h):
Clean up the stack if necessary.
ENDIF
ENDIF


一些相關的表格

Table 1 - IPL Table and BCV Table Entry Data Structure
Name Offset Size Description
deviceType 00h WORD See definitions below
statusFlags 02h WORD See bit definitions below
bootHandler 04h FAR PTR Far pointer to address of boot handler
descString 08h FAR PTR Far pointer to ASCIIZ description string
expansion 0Ch DWORD Reserved for future expansion

deviceType:
00h = Reserved
01h = Floppy
02h = Hard disk
03h = CD-ROM
04h = PCMCIA
05h = USB device
06h = Embedded network
07h..7Fh = Reserved
80h = BEV device
81h..FEh = Reserved
FFh = Unknown

Table 2 - PnP Option ROM Header
Offset Size Value Description
00h BYTE 55h Signature byte 1
01h BYTE AAh Signature byte 2
02h BYTE Varies Option ROM length in 512-byte blocks
03h DWORD Varies Initialization entry point
07h 17BYTES Varies Reserved.
18h WORD Varies Offset to PCI data structure
1Ah WORD Varies Offset to expansion header structure

Table 3 - PnP Expansion Header
0ffset Size Value Description
00h BYTE '$' Signature byte 1
01h BYTE 'P' Signature byte 2
02h BYTE 'n' Signature byte 3
03h BYTE 'P' Signature byte 4
04h BYTE 01h Structure revision
05h BYTE Varies Length (in 16 byte increments)
06h WORD Varies Offset of next header (0000h if none).
08h BYTE 00h Reserved
09h BYTE Varies Checksum
0Ah DWORD Varies Device identifier
0Eh WORD Varies Pointer to manufacturer string (Optional)
10h WORD Varies Pointer to product name string (Optional)
12h 3BYTES Varies Device type code
15h BYTE Varies Device indicators
16h WORD Varies Boot Connection Vector (BCV), 0000h if none
18h WORD Varies Disconnect Vector (DV), 0000h if none
1Ah WORD Varies Bootstrap Entry Vector (BEV), 0000h if none
1Ch WORD 0000h Reserved
1Eh WORD Varies Static resource information vector, 0000h if none

Table 4 - PCI Data Structure
00h BYTE 'P' Signature byte 1
01h BYTE 'C' Signature byte 2
02h BYTE 'I' Signature byte 3
03h BYTE 'R' Signature byte 4
04h WORD Varies Vendor Identification
06h WORD Varies Device Identification
08h WORD Varies Pointer to Vital Product Data
0Ah WORD Varies PCI Data Structure Length
0Ch BYTE Varies PCI Data Structure Revision
0Dh 3BYTES Varies Class Code
10h WORD Varies Image Length
12h WORD Varies Revision Level of Code/Data
14h BYTE Varies Code type
15h BYTE Varies Indicator
16h WORD Reserved

2009年4月2日 星期四

MASM note: asume

Since the ds register can be changed at run time (using an instruction like mov ds,ax), any segment can be a data segment.

When you specify a segment in your program, not only must you tell the CPU that a segment is a data segment, but you must also tell the assembler where and when that segment is a data (or code/stack/extra/F/G) segment.

Note that this directive does not modify any of the segment registers, it simply tells the assembler to assume the segment registers are pointing at certain segments.

assume directive modifies the assembler's behavior from the point MASM encounters it until another assume directive changes the stated assumption.


DSEG1 segment para public 'DATA'
var1 word ?
DSEG1 ends

DSEG2 segment para public 'DATA'
var2 word ?
DSEG2 ends

CSEG segment para public 'CODE'
assume CS:CSEG, DS:DSEG1, ES:DSEG2
mov ax, seg DSEG1
mov ds, ax
mov ax, seg DSEG2
mov es, ax

mov var1, 0
mov var2, 0
.
.
.
assume DS:DSEG2
mov ax, seg DSEG2
mov ds, ax
mov var2, 0
.
.
.
CSEG ends
end


The 80x86 microprocessor doesn't know about segments declared within your program, it can only access data in segments pointed at by the cs, ds, es, ss, fs.

When the assembler encounters an instruction of the form mov var1,0, the first thing it does is determine var1's segment. It then compares this segment against the list of assumptions the assembler makes for the segment registers. If you didn't declare var1 in one of these segments, then the assembler generates an error claiming that the program cannot access that variable. If the symbol (var1 in our example) appears in one of the currently assumed segments, then the assembler checks to see if it is the data segment. If so, then the instruction is assembled as described in the appendices. If the symbol appears in a segment other than the one that the assembler assumes ds points at, then the assembler emits a segment override prefix byte, specifying the actual segment that contains the data.

In the example program above, MASM would assemble mov VAR1,0 without a segment prefix byte. MASM would assemble the first occurrence of the mov VAR2,0 instruction with an es: segment prefix byte since the assembler assumes es, rather than ds, is pointing at segment DSEG2. MASM would assemble the second occurrence of this instruction without the es: segment prefix byte since the assembler, at that point in the source file, assumes that ds points at DSEG2. Keep in mind that it is very easy to confuse the assembler.


CSEG segment para public 'CODE'
assume CS:CSEG, DS:DSEG1, ES:DSEG2
mov ax, seg DSEG1
mov ds, ax
.
.
.
jmp SkipFixDS

assume DS:DSEG2

FixDS: mov ax, seg DSEG2
mov ds, ax
SkipFixDS:
.
.
.
CSEG ends
end


Notice that this program jumps around the code that loads the ds register with the segment value for DSEG2. This means that at label SkipFixDS the ds register contains a pointer to DSEG1, not DSEG2. However, the assembler isn't bright enough to realize this problem, so it blindly assumes that ds points at DSEG2 rather than DSEG1. This is a disaster waiting to happen. Because the assembler assumes you're accessing variables in DSEG2 while the ds register actually points at DSEG1, such accesses will reference memory locations in DSEG1 at the same offset as the variables accessed in DSEG2. This will scramble the data in DSEG1 (or cause your program to read incorrect values for the variables assumed to be in segment DSEG2).

For beginning programmers, the best solution to the problem is to avoid using multiple (data) segments within your programs as much as possible. Save the multiple segment accesses for the day when you're prepared to deal with problems like this. As a beginning assembly language programmer, simply use one code segment, one data segment, and one stack segment and leave the segment registers pointing at each of these segments while your program is executing. The assume directive is quite complex and can get you into a considerable amount of trouble if you misuse it. Better not to bother with fancy uses of assume until you are quite comfortable with the whole idea of assembly language programming and segmentation on the 80x86.

The nothing reserved word tells the assembler that you haven't the slightest idea where a segment register is pointing. It also tells the assembler that you're not going to access any data relative to that segment register unless you explicitly provide a segment prefix to an address. A common programming convention is to place assume directives before all procedures in a program. Since segment pointers to declared segments in a program rarely change except at procedure entry and exit, this is the ideal place to put assume directives:


assume ds:P1Dseg, cs:cseg, es:nothing
Procedure1 proc near
push ds ;Preserve DS
push ax ;Preserve AX
mov ax, P1Dseg ;Get pointer to P1Dseg into the
mov ds, ax ; ds register.
.
.
.
pop ax ;Restore ax's value.
pop ds ;Restore ds' value.
ret
Procedure1 endp


The only problem with this code is that MASM still assumes that ds points at P1Dseg when it encounters code after Procedure1. The best solution is to put a second assume directive after the endp directive to tell MASM it doesn't know anything about the value in the ds register:


.
.
.
ret
Procedure1 endp
assume ds:nothing


Although the next statement in the program will probably be yet another assume directive giving the assembler some new assumptions about ds (at the beginning of the procedure that follows the one above), it's still a good idea to adopt this convention. If you fail to put an assume directive before the next procedure in your source file, the assume ds:nothing statement above will keep the assembler from assuming you can access variables in P1Dseg.

Segment override prefixes always override any assumptions made by the assembler. mov ax, cs:var1 always loads the ax register with the word at offset var1 within the current code segment, regardless of where you've defined var1. The main purpose behind the segment override prefixes is handling indirect references. If you have an instruction of the form mov ax,[bx] the assembler assumes that bx points into the data segment. If you really need to access data in a different segment you can use a segment override, thusly, mov ax, es:[bx].

In general, if you are going to use multiple data segments within your program, you should use full segment:offset names for your variables. E.g., mov ax, DSEG1:I and mov bx,DSEG2:J. This does not eliminate the need to load the segment registers or make proper use of the assume directive, but it will make your program easier to read and help MASM locate possible errors in your program.

The assume directive is actually quite useful for other things besides just setting the default segment. You'll see some more uses for this directive a little later in this chapter.

http://www.arl.wustl.edu/~lockwood/class/cs306/books/artofasm/Chapter_8/CH08-3.html#HEADING3-98