小華的部落格

搜尋此網誌

網頁

星期四, 4月 22, 2010

Cx State

最近很少更新部落格,都被一些網友說"小華已經很久沒更新了"...所以就先上來更新些文章QQ..

先說說Cx State 在BIOS端是怎麼跟CPU還有ASL code甚至是SetupMenu串再一起的.

首先,一般BIOS會在SetupMenu中建立出一些item來控制Cx State的Enable/Disable,這部分會因為各家BIOS在SetupMenu上的做法不同而有所不同,但是你只要知道一個東西! 就是一定會有一個地方儲存好SetupMenu上選項內的設定值. (Ex: CMOS/EFI Variable...)

接著,在PPM 的相關 Reference code那邊 (一般都是Ixxel的CPU的PPM reference code)會去參考SetupMenu內的設定值來組態CPU內部的MSR暫存器,至於他是如何得到SetupMenu的設定值又會因為不同的BIOS而有所不同,像是EFI就可能透過Policy來得到,所以要有人把SetupMenu的值放進去Policy內,這樣子Reference code才能參考SetupMenu的選項來組態MSR!

當這邊在一般組態MSR時,他會一邊修改Acpi Table! 例如你想關閉C2/C3,大家都知道去ACPI Table把值改成>100 或是 > 1001就可以了,所以這邊的Reference code會去參考你的SetupMenu的設定值來決定要不要修改ACPI Table內那個回報給OS的值!

其他的部分有牽扯到ASL code的部分我可能就不明說了,請大家搜尋CFGD這個值,看看他在哪邊被放進,然後ASL code為什麼要判斷他! 追個一遍就清楚了^^Y

星期三, 4月 07, 2010

MVP

去年一整年都在忙EFI的案子,在眾多的學長以及同事的幫忙下案子也在驚濤駭浪中完成了!


這個榮譽是屬於大家的,沒有你們的幫忙,我就不會有這個獎項!



要感謝T老大這些主管們的情義相挺,也要感謝V哥/Jackson/Motor 的友情贊助! 感謝雅莉姐,Vincent的幫忙,在這種資源匱乏下一路扶持過來! 也感謝犀利猛先生一路糾正我許多BIOS觀念,特別要感謝 H.C 在小弟忙結婚那段時間一直被凹~

還有其他在背後默默幫助我的同事們也感謝你們~因為有你們,才會有這番榮耀!

星期六, 4月 03, 2010

DirectX v.s VGA driver

最近重新安裝我的工作機的作業系統; 在安裝後,順便安裝了平常在玩的網路遊戲光碟,
結果在執行的時候,卻發現他跳出了一個錯誤訊息:

File=dxvideo.cpp,Line=649,Code=80004001

原本以為是VGA driver的問題,所以花了很多時間去找了最新版的Nvidia driver重新安裝,
然後再去抓了DirectX for XP SP3的更新檔來安裝! 但是結果還是沒辦法進入遊戲之中!

因此秉持著研究的精神,先去研究了一下這個網路遊戲需要的解析度,發現這個2D網路遊戲
神州Online 是預設 640 x 480 x 16 的解析度,而網路上相關的討論是說去修改遊戲目錄內的

Online.ini:
[SYSTEM]
Width = 800
Height = 600
Fullscreen = 0
Switchscreen = 1

把他強制設定成800 x 600這樣子就可以進入遊戲,然後不要全螢幕(Fullscreen = 0) ,
而Switchscreen =1是用來設定這款遊戲能不能用Alt+Enter 來切換視窗化!
雖然這樣子可以進入遊戲 ,但是畫面就是變成視窗化那樣子! 玩起來總是感覺怪怪的!

因此很不死心的繼續追問題~在google大神找了很久之後發現可以利用Dxdiag這個工具來檢
查一下你的系統的DirectX有沒有甚麼問題!

因此我就選了開始->執行->鍵入dxdiag,然後就看到測試的視窗出現了!
從畫面上可以看到我的顯示晶片是Quadro NVS 140M,然後你可以點選【測試DirectDraw】
或是【測試Direct3D】,我是先選了【測試DirectDraw】。

然後就看到了下面的地方出現了:
DirectDraw test results: Failure at step 17 (SetDisplayMode to 640x480x16): HRESULT = 0x80004001 (Not implemented)
Direct3D 7 test results: Failure at step 39 (SetDisplayMode to 640x480x16): HRESULT = 0x80004001 (Not implemented)


啥米? 我的螢幕解析度不支援640 x 480??! 所以我就看了一下我的螢幕解析度的支援!
還真的不能使用640 x 480,最小只到800 x 600 ,難怪我的遊戲一直會出現dxvideo.cpp 有問題!
因為根本就沒辦法切過去640 x 480!

而知道的問題的原因之後,就開始針對Quadro NVS 140M來找解決方案!
然後就找到了一個網站跟他所提到的工具可以解決這個顯示晶片不支援640x480的方法:

http://werdna1222coldcodes.blogspot.com/2010/02/directdraw-init-failed.html

於是在使用了這個RivaTuner的方式自己增加了一個640x480x16的解析度之後,再重新開機!
開機完重新執行dxdiag跟我的網路遊戲,結果問題真的就解決了耶!

所以結論就是: 太好的VGA,會讓你沒辦法玩舊款遊戲! 但是想玩遊戲,就只好多認真點學些
東西!
希望這篇文章能夠幫助一些人可以多玩一些遊戲啦~ 呵呵!

星期二, 3月 23, 2010

64 bit 組合語言

64 bit 組合語言需要注意事項:

1.多了一些64 bit暫存器
r8,r9,r10,r11,r12,r13,r14,r15

2.暫存器長度變成64 bit
rax,rbx,rcx,rdx,rsi,rdi,rsp,rbp

3.堆疊操作指令要對應64 bit暫存器
ex: (Push, pop, call, ret, enter, and leave) push eax;這是非法的
push rax;這是合法的

4.RIP變成合法化來存取資料
mov,rax,qword ptr [rip+300];以前IP只能當成程式記數器,現在可以參與資料獲取 也因此在64 bit下,DS/ES/SS/CS變的很沒有意義了!

5.Calling Conventions (呼叫慣例)變成Callee(被呼叫者)不需要清除Stack,這是Caller呼叫者的工作

EX:
Function(arg1,arg2,arg3,arg4,arg5) ,假設arg1~4都是整數,他們分別會被放進去對應的暫存器
RCX: 1st integer arg
RDX: 2nd integer arg
R8: 3rd integer arg
R9: 4th integer arg

arg5才會被放進去Stack,但是這個stack會先幫這幾個arg預留空間,
所以第5個參數會是放在 rsp+0x20的地方!

這個概念跟我們以前32 bit觀念不同,他並不是__cdecl/ __stdcall/ __fastcall
所以從下面的範例中可以看到呼叫者會去清除stack:

The stack must be kept 16-byte aligned. Since the "call" instruction
pushes an 8-byte return address, this means that every non-leaf
function is going to adjust the stack by a value of the form 16n+8 in
order to restore 16-byte alignment.

ex:
void SomeFunction(int a, int b, int c, int d, int e);
void CallThatFunction()
{
SomeFunction(1, 2, 3, 4, 5);
SomeFunction(6, 7, 8, 9, 10);
}

On entry to CallThatFunction, the stack looks like this:
xxxxxxx0 .. rest of stack ..
xxxxxxx8 return address <- RSP

Due to the presence of the return address, the stack is misaligned. CallThatFunction sets up its stack frame, which might go like this:

    sub    rsp, 0x28

Notice that the local stack frame size is 16n+8, so that the result is a realigned stack.

xxxxxxx0 .. rest of stack ..
xxxxxxx8 return address
xxxxxxx0
(arg5)
xxxxxxx8
(arg4 spill)
xxxxxxx0
(arg3 spill)
xxxxxxx8
(arg2 spill)
xxxxxxx0
(arg1 spill) <- RSP

Now we can set up for the first call:

        mov     dword ptr [rsp+0x20], 5     ; output parameter 5
mov r9d, 4 ; output parameter 4
mov r8d, 3 ; output parameter 3
mov rdx, 2 ; output parameter 2
mov rcx, 1 ; output parameter 1
call SomeFunction ; Go Speed Racer!

When SomeFunction returns, the stack is not cleaned, so it still looks like it did above. To issue the second call, then, we just shove the new values into the space we already reserved:

        mov     dword ptr [rsp+0x20], 10    ; output parameter 5
mov r9d, 9 ; output parameter 4
mov r8d, 8 ; output parameter 3
mov rdx, 7 ; output parameter 2
mov rcx, 6 ; output parameter 1
call SomeFunction ; Go Speed Racer!
CallThatFunction is now finished and can clean its stack and return.
        add     rsp, 0x28
ret

Notice that you see very few "push" instructions in amd64 code, since the paradigm is for the caller to reserve parameter space and keep re-using it.

這種呼叫慣例比較像是結合了__cdecl/ __fastcall 的特性:
__cdecl : 在呼叫者(Callee) return,由呼叫者(Caller)清除堆疊
__fastcall : 32bit時是將最左邊兩個參數會放在ecx跟edx ,而64 bit 這邊是放在rcx,rdx,r8,r9

Reference
http://blogs.msdn.com/oldnewthing/archive/2004/01/14/58579.aspx

星期六, 3月 13, 2010

安裝VB6的問題

有些人可能有些經驗在安裝VB6時會出現 "找不到acme安裝程式" 的錯誤訊息!
這先就提供你一個方式可以解決這個問題.

首先你先建立一個批次檔,例如叫做VB6Setup.bat
然後輸入下面的這些內容:

@ECHO OFF
set VB6FOLDER=F:\vb6
del %temp%\*.* /y
%VB6FOLDER%\SETUP\ACMSETUP.EXE /T VB98ENT.STF /S %VB6FOLDER% /n "" /o "" /k "0000000000" /b 1

那個VB6FOLDER的路徑你可以設定成你的VB6放置的位置
例如你是放在光碟機,你就可以寫成set VB6FOLDER=E:

然後執行這個批次檔,然後你就會看到開始安裝的畫面了!

星期三, 3月 03, 2010

有趣的Code-BootOption 的建立

今天在看BootOption建立的code時發現他會去跳掉同時有SimpleFileSystem&BlkIo protocol的Handle,只留下Hanlde 上面有SimpleFileSystem的!

雖然很搞不清楚他為什麼要這樣做,但是一般情況下不可能只有SimpleFileSystem存在!
所以應該是要防呆吧! 怕哪一天真的有Hanlde上面只掛SimpleFileSystem而沒有BlkIo.

這種Hanlde他還是會幫他建立出一個BootOption!


gBS->LocateHandleBuffer (
...
&gEfiSimpleFileSystemProtocolGuid,
...
);
for (Index = 0; Index < NumberFileSystemHandles; Index++) {
Status = gBS->HandleProtocol (
...
&gEfiBlockIoProtocolGuid,
(VOID **) &BlkIo
);
if (!EFI_ERROR (Status)) {

continue; //這邊會Skip
}
...
}

星期日, 2月 28, 2010

C語言複習3

~複習一下一些指標的概念~

問題一: 底下的這個做法的概念
int a;
*&a=30;

Ans:

int a; 可以看成 _A WORD ?
&a 可以看成 LEA BX,_A
* 可以看成 MOV 東西到某個記憶體,所以*&a=30 等同於MOV [BX],30

其實他是等同於a=30,但是這樣子寫會跑更慢!code更大!


問題二:
*200 = 30;

Ans:
這樣子寫是非法的,因為雖然a 在記憶體200的位址,但是你不知道a是多大
所以你要告訴Compiler要一次搬兩個byte. 所以(int *) 等同於word ptr.

*(int *)200=30;

用組語來看會類似 mov word ptr [200],30
其中word ptr是假指令,用來一次搬兩個BYTE
[200] 代表記憶體位址200

星期一, 2月 22, 2010

C語言複習2

1. &&與& 容易混淆
&& 是邏輯運算
& 是AND運算

EX: 當 x=1,y=2
if(x&&y) 這邊會是1&&2=TRUE
if(x&y) 這邊會是1&2 = 0 = FALSE

2.條件式判斷
Expression1?Expression2:Expression3

EX: 當x>3 成立時,會執行x=1

XXX= x > 3?1:0

他等同於:
if(x>3)
XXX=1
else
XXX=0

3.逗號語法
Expression1,Expression2,Expression3,....ExpressionN
if( x+1,y+2,z<=3)
k=1
else
k=0
他會依序執行將 X+1,Y+2,直到遇到判斷式Z<=3時才會跳出if()
簡單說就是當Z<=3成立時(TRUE),會得到K=1,雖然沒有人會這樣子寫,但是可以這樣子用!

一般比較常看到的寫法會是:
while(ch=getch(),ch=='a')
{
...
}

4.陣列
array[i]等同於*(array+i)

C語言複習

1.變數有效區(Scope)
EX1:
{
int i; //只在括號內有效
}

EX2:
static int i; //只在本文件內有效

EX3:
extern int i; //不管幾個文件中都只有一個實體i;
//他等同於你在File Scope(你在寫#include的那個區塊)中宣告int i;
//只是為了可讀性所以加入extern 這個關鍵字,不加也是可以!

2.for/while/do..while/break/continue

while(Expression)
Statement


for(Expression1;Expression2;Expression3)
Statement


do{
Statement
}while(Expression)

星期一, 10月 19, 2009

InsertList

最近常看EFI的code,所以就順便整理一下一些C的資料結構的東東。

1.EFI中都是喜歡使用雙向鏈結串列(doubly linked list)
在雙向鏈結串列中的節點(Node)至少有2個欄位,一個為向後結欄 (BackLink) ,另一個為向前鏈結欄 ( ForwardLink ) 。其必要的宣告為:
 
    typedef struct node *node_ptr ;
    typedef struct node {
        node_ptr Flink ;
        node_ptr Blink ;
        } ;

2.插入鏈結串列可以從頭插入或是從尾插入兩種,底下是圖示來表示這兩種差別。
InsertHeadList();
InsertTailList();



這些鏈結的運用在EFI中隨處可見,所以在這邊留下筆記來紀錄一下學習心得!

星期五, 10月 09, 2009

NMAKE (1)

IDE用習慣的人應該很少會去使用到makefile,但是為了生存下去,所以我也開始學習這個東西的用法.

而為了測試NMAKE.EXE 的使用方式,所以自己就會去做一些小實驗來了解一些東西,然後順便把他紀錄下來。

底下是我為了想知道$** 跟$@ 是代表什麼用意時所做的一些實驗,因為是初學者,所以各位看官就別取笑小弟我的土法煉鋼法喔~

1.準備test.mak,其內容如下:

SOURCE_FILE_NAME = test.mak
DEST_DIR = c:\maktest
BASE_NAME = test

$(DEST_DIR)\$(BASE_NAME).bin : $(SOURCE_FILE_NAME)
echo $**
echo $@
copy $** $@

all: $(BIN_DIR)\$(BASE_NAME).bin

2.進入NAMKE環境,鍵入:


C:\maktest\>NMAKE /F test.mak

3.結果

echo test.mak
test.mak
echo c:\maktest\test.bin
c:\maktest\test.bin
copy test.mak c:\maktest\test.bin
1 file(s) copied.

C:\maktest>

4.結論

可以看的到$** 是代表$(SOURCE_FILE_NAME)
而$@ 看起來是代表$(DEST_DIR)\$(BASE_NAME).bin

所以copy $** $@ 等同於 copy test.mak c:\maktest\test.bin

從makefile寫法來看:
$**應該就是[dependency]
$@ 應該就是[target]

[target]: [dependency] [dependency]
[TAB][rule] <--要注意,寫rule之前要加tab.
[TAB][rule]

星期二, 10月 06, 2009

C語言原來不能亂放空白字元!


寫Code的過程中發現原來巨集後面不能加"空白"字元!

見下圖中紅色框框的地方,如果有空白字元會Compiler error.

星期四, 6月 18, 2009

Visual C++ 編譯器選項

最近常常在寫C語言且被編譯器的選項困擾,所以就到微軟網站找到相關的資訊。
因為怕微軟更新網站資料就消失了,因此在這邊記錄選項的部分內容,如果有興趣了解更多的人可以到經由連結到微軟網站得到更多詳細的訊息:

Visual C++ 編譯器選項
選項 用途

@

指定回應檔。

/?

列出編譯器選項。

/AI

指定一個要搜尋的目錄,以解析傳遞給 #using 指示詞的檔案參考。

/analyze

啟用程式碼分析

/arch

在程式碼產生時使用 SSE 或 SSE2 指令 (僅適用於 x86)。

/bigobj

增加 .obj 檔中可定址區段的數目

/C

在前置處理過程中保留註解。

/c

編譯而不連結。

/clr

產生輸出檔案,以便在 Common Language Runtime 上執行。

/D

定義常數和巨集。

/doc

將文件註解處理成 XML 檔案

/E

複製前置處理器輸出至標準輸出。

/EH

指定例外處理模型。

/EP

複製前置處理器輸出至標準輸出。

/errorReport

讓您直接提供內部編譯器錯誤 (ICE) 資訊給 Visual C++ 團隊

/F

設定堆疊大小。

/favor

產生已為特定 x64 架構最佳化的程式碼,或為 AMD64 和 延伸記憶體 64 技術 (Extended Memory 64 Technology, EM64T) 架構中微架構特性最佳化的程式碼

/FA

建立清單檔。

/Fa

設定清單檔名稱。

/FC

顯示在診斷測試中傳遞給 cl.exe 的原始程式檔完整路徑

/Fd

重新命名程式資料庫檔案。

/Fe

重新命名可執行檔。

/FI

前置處理指定的包含檔。

/Fm

建立對應檔 (Mapfile)。

/Fo

建立目的檔。

/fp

指定浮點行為

/Fp

指定先行編譯標頭檔的名稱。

/FR

/Fr

產生瀏覽器檔案。

/FU

強制使用某一檔名,就如同它已傳遞給 #using 指示詞一樣。

/Fx

將插入的程式碼與原始程式檔合併。

/G1

為 Itanium 處理器執行最佳化。只有 IPF 跨平台編譯器或 IPF 原生編譯器才有提供。

/G2

為 Itanium2 處理器最佳化 (預設值為 /G1 與 /G2 之間),只有 IPF 跨平台編譯器或 IPF 原生編譯器才有提供。

/GA

對 Windows 應用程式進行程式碼最佳化。

/Gd

使用 __cdecl 呼叫慣例 (僅適用於 x86)。

/Ge

啟動堆疊探查。

/GF

啟用字串共用。

/GH

呼叫攔截 (Hook) 函式 _pexit

/Gh

呼叫攔截 (Hook) 函式 _penter

/GL

啟用整個程式最佳化。

/Gm

啟用最少重建。

/GR

啟用執行階段型別資訊 (RTTI)。

/Gr

使用 __fastcall 呼叫慣例 (僅適用於 x86)。

/GS

緩衝處理安全性檢查。

/Gs

控制堆疊探查。

/GT

對使用靜態執行緒區域儲存區配置的資料支援 Fiber 安全性。

/GX

啟用同步例外處理。

/Gy

啟用函式階層連結。

/GZ

/RTC1 相同。/RTC (執行階段錯誤檢查)

/Gz

使用 __stdcall 呼叫慣例 (僅適用於 x86)。

/H

限制外部 (公用) 名稱的長度。

/HELP

列出編譯器選項。

/homeparams

在函式進入時,強制暫存器中所傳遞的參數寫入至堆疊上的位置。這個編譯器選項只適用於 x64 編譯器 (原生和跨平台編譯)

/hotpatch

建立可線上修補的影像

/I

搜尋包含檔的目錄。

/J

變更預設 char 型別。

/LD

建立動態連結程式庫。

/LDd

建立偵錯動態連結程式庫。

/link

傳遞指定的選項給 LINK。

/LN

建立 MSIL 模組

/MD

使用 MSVCRT.lib 建立多執行緒 DLL。

/MDd

使用 MSVCRTD.lib 建立偵錯多執行緒 DLL。

/MT

使用 LIBCMT.lib 建立多執行緒可執行檔。

/MTd

使用 LIBCMTD.lib 建立偵錯多執行緒可執行檔。

/nologo

隱藏登入程式的啟始資訊。

/O1

建立小型程式碼。

/O2

建立快速程式碼。

/Ob

控制內嵌展開。

/Od

停用最佳化。

/Og

使用全域最佳化。

/Oi

產生內建函式。

/openmp

在原始程式碼中啟用 #pragma omp

/Os

偏好小的程式碼。

/Ot

偏好快的程式碼。

/Ox

使用最大最佳化 (/Ob2gity /Gs)。

/Oy

省略框架指標 (僅適用於 x86)。

/QIfist

在必須從浮點型別轉換為整數型別時,抑制 _ftol (僅適用於 x86)。

/QIPF_B

根據 B CPU 逐步偵錯的 errata,不會產生指令順序,而導致意外結果(僅適用於 IPF)。

/QIPF_C

根據 C CPU 逐步偵錯的 errata,不會產生指令順序,而導致意外結果(僅適用於 IPF)。

/QIPF_fr32

不要使用上層 96 浮點暫存器(僅適用於 IPF)。

/QIPF_noPIC

產生影像加上與位置有關的程式碼 (僅適用於 IPF)

/QIPF_restrict_plabels

為不在執行階段建立函式的程式增強效能(僅適用於 IPF)。

/P

將前置處理器輸出寫入檔案。

/RTC

啟用執行階段錯誤檢查。

/showIncludes

在編譯時顯示包含檔清單。

/Tc

/TC

指定 C 原始程式檔。

/Tp

/TP

指定 C++ 原始程式檔。

/U

移除某個預先定義巨集。

/u

移除所有預先定義巨集。

/V

設定版本字串。

/vd

抑制或啟用隱藏的 vtordisp 類別成員。

/vmb

對指向成員的指標使用最佳基底。

/vmg

對指向成員的指標使用完整一般性。

/vmm

宣告多重繼承。

/vms

宣告單一繼承。

/vmv

宣告虛擬繼承。

/W

設定警告層級。

/w

停用所有警告。

/Wall

啟用所有警告,包括預設停用的警告。

/WL

從命令列編譯 C++ 原始程式碼時啟用一行錯誤和警告訊息診斷。

/Wp64

偵測 64 位元可移植性問題。

/X

忽略標準 Include 目錄。

/Y-

忽略目前組建中所有其他先行編譯標頭編譯器選項。

/Yc

建立先行編譯標頭檔。

/Yd

將完整的偵錯資訊置於所有目的檔中。

/Yl

在建立偵錯程式庫時插入一個 PCH 參考

/Yu

在建置時使用先行編譯標頭檔。

/Z7

產生 C 7.0 相容的偵錯資訊。

/Za

停用語言擴充功能。

/Zc

指定 /Ze 下的標準行為。/Za、/Ze (停用語言擴充功能)

/Ze

啟用語言擴充功能。

/Zg

產生函式原型。

/ZI

將偵錯資訊包括在與「編輯後繼續」相容的程式資料庫中。

/Zi

產生完整偵錯資訊。

/Zl

從 .obj 檔案移除預設程式庫名稱 (僅適用於 x86)。

/Zm

指定先行編譯標頭的記憶體配置上限。

/Zp

封裝結構成員。

/Zs

僅檢查語法。

/Zx

產生可偵錯最佳化程式碼,只有 IPF 跨平台編譯器或 IPF 原生編譯器才有提供


Reference


星期日, 5月 17, 2009

Intel EFI Specs資訊

整理一下以前在Intel網站抓的一些Specs資訊。
怕自己忘記去哪下載!
所以就留下筆記記錄一下!

這些都是Intel 所提供的相關文件,有興趣的可以去Intel網站抓。

ftp://download.intel.com/technology/framework/docs
















































































































































































ftp://download.intel.com/technology/framework/docs
Reference
www.intel.com

痞子英雄

最近在迷這部電視劇,真是令人熱血了起來! 好久沒看到台灣有如此棒的電視劇了!
劇中的高雄風景真的很美,讓我又有想去痞子一日遊的衝動了~

http://www.pts.org.tw/~web03/ruffian_hero/index1.htm

星期三, 5月 13, 2009

AfterG3 bit

After G3 bit : 用來設定AC電源重新供電後的系統狀態

狀態1 : S0/S1/S3 電源有問題,重新上電
1=保持S5
0=啟動

狀態2 : S4 電源有問題,重新上電
1=保持S4
0=啟動

狀態3 : S5 電源有問題,重新上電
1=保持S5
0=啟動

星期二, 4月 21, 2009

C/C++ Compiler Intrinsics

Compiler Intrinsics 的相關連結,因為最近寫C語言時常在使用所以收集此連結!

EX:

__debugbreak();
__enable();
__disable();

http://msdn.microsoft.com/zh-tw/library/26td21ds.aspx

星期三, 1月 21, 2009

老程式也有它的好處

大家都知道debug.com的用法,不過他還有一個應用的方式是我經常使用的!
剛好前陣子公司同事也有分享這個用法,所以就順便把他在做個簡單的介紹。

老程式Debug.com 有支援輸入/輸出導向,也就是以前DOS下的 ">" 跟"<" 符號所做的事情, 而他的用法很簡單,你只要在一個文字檔中先寫好你要做的事情,然後導入到Debug.com中 就可以了,而Debug.com就會依照你的文字檔的動作去做事情! 例如原本你使用debug.com時你做了下面的動作 -d
-q

那麼你就可以寫成一個Test.txt,然後裡面的內容是:
d
q

接著進入DOS Cmd prompt ,導入這個文字檔給debug.com 例如:
C:\> debug < test.txt

這樣子debug就會自動幫你執行d指令,還有q 離開debug.com.

而下面是一個Dump PIRQ的批次檔,我會自己去F Segment內找到'$PIR' 的位址,然後透過D指令去Dump 這個記憶體,接著把Dump的內容寫到一個檔案中:

@ECHO OFF
REM ============= Find PIRQ ===================
ECHO. s f000:0 ffff '$PIR' > FindPIRQ.txt
ECHO. q >> FindPIRQ.txt
debug <> PIRQAddr.txt

REM ============= Set variable ===================
FOR /F %%A in ('FINDSTR /C:"F000" PIRQAddr.txt') do SET FSEG=%%A

REM ============= Dump PIRQ ===================
ECHO. d %FSEG% > DumpPIRQ.txt
ECHO. d >> DumpPIRQ.txt
ECHO. d >> DumpPIRQ.txt
ECHO. d >> DumpPIRQ.txt
ECHO. d >> DumpPIRQ.txt
ECHO. q >> DumpPIRQ.txt

debug <> Pirq.txt

ECHO.
ECHO. Output: PIRQ.txt
ECHO.

DEL FindPIRQ.txt
DEL PIRQAddr.txt
DEL DumpPIRQ.txt
pause


底下是我產生的文字檔內的內容:
- d F000:DE80

F000:DE80 24 50 49 52 00 01 60 01-FF FF 00 00 86 80 2E 12 $PIR..`.........
F000:DE90 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
F000:DEA0 00 00 00 F8 DE 00 F8 DE-00 F8 DE 00 F8 DE 00 00 ................
F000:DEB0 00 38 60 E0 1C 00 F8 DE-00 F8 DE 00 F8 DE 00 00 .8`.............
F000:DEC0 00 08 60 E0 1C 00 F8 DE-00 F8 DE 00 F8 DE 00 00 ..`.............

星期日, 1月 18, 2009

人生無常

『人生無常』~ 以前總覺得『無常』是無法接觸到的,是看不到摸不到的! 一旦它讓你看到/接觸到時真是令人難以承受之痛!

去年,2008.11.18 我敬愛的叔叔走了,當時很難過;一個我從小當成典範的長輩一個疼愛我的長輩離開了我,但想到他能夠自癌病中解脫,能夠到達另一個世界去未嘗不是一種新的祝福!

但人生就是如此無常,二個月後的昨天2009.01.18,我自小照顧我的奶奶因為心肌梗塞突然送進加護病房急救,在我回到苗栗時奶奶就已經走了! 最後一面沒有見到,心好痛! 在陪伴著、看著她安詳的躺在那時,淚水一直停不下來!

『人生無常』,希望大家能夠好好珍惜身邊的親友與你最愛的人! 平凡的幸福才是真正的幸福,一早起來你的親友和你愛的人能夠笑著跟你打聲招呼,這種平凡的幸福在此刻的我真的難以擁有啊!

星期日, 1月 11, 2009

EFI 的新體驗~

以前在做案子的時候只管如何去把OEM/ODM features做出來,所以比較少時間去慢慢的消化EFI code的內容,其實在EFI中有很多小地方的事情是以前學C語言的時候從來都沒有注意過的事情!而這些小地方也讓我對C語言有了更進一步的體驗~

像是最近研究EFI code的過程中發現了一個好玩的東西,原來C也有類似 Strong/Weak 的寫法!
以前一直笨笨的想說C要怎麼去做這部份的東西,還一直以為做不到! 原來這些東西都已經有參考範例在EFI code之中了! 只是以前壓根子都沒想過原來C可以這樣玩~在慢慢消化EFI code的過程中還真的是驚奇不斷咧!

從最近學習EFI code的過程之中,真的讓我對C語言有了更深一層的了解;在此時回頭去想想以前自己在學校中老是以為我已經對C有一定層度的認知~現在才發現 "原來我只是個井底之蛙啊"....