2011年4月21日 星期四

How to share your knowledge to Blogger with WL Writer and PicPack / 如何分享妳的知識到部落格(使用Writer寫文,PicPack截圖)

Agenda:


(A) 前言
(B) Windows Live! Writer(寫文) + PicPack(截圖)

(A) 前言


大家畢業也將近一年了,我們平常都忙著做事,雖然工作上稍有領略,但都只能專注於手頭上的專業,利用分享及po文的過程,來強化個人記憶及互相學習或許是個不錯的idea,這個平台還盼各位一起努力,大家一起成長吧!!

Q: 為甚麼要用部落格?
Ans: 最重要的考量是:
- 便於分享,要能多位作者功能。
- 編輯便利,要有方便編輯的配套、快速的網站瀏覽速度。
- 便於討論,要有留言功能。
- 長期有效,盡量不要有網路空間經營不下去,然後搬站的資料轉移的麻煩。
- 免費使用。
所以我挑上Google Blogger做為共享的部落格,是有符合以上要求的。
原有意使用雲端筆記本,但缺少留言討論,所以作罷。

Q: Goole Blogger 的缺點?
Ans: 不是每個人都有意願及需要去申請Google帳號,現在新申請帳號還得留電話註冊,感覺不是很爽。

Q: 編輯如何快速、便利?
Ans: 用 Windows Live! Writer 寫文,再配上PicPack截圖,操他媽方便、簡單。

(B) Windows Live! Writer(寫文) + PicPack(截圖)


(1)下載及安裝,這應該不用講。
(2)以下是帳號設定SOP
選擇”其他服務”
image
網址如下,直接複製、貼上吧,http://ui701-0xlab.blogspot.com/
image
中間會問妳要不要發一篇測試用的文,以偵測部落格的主題(顏色等外觀的東西),選Yes吧
image
然後就設定好了。
(3)接下來就操他媽的簡單了,記得po完文後,替這篇文上個分類用的標籤,方便其他人分類閱讀,目前這幾類是我隨便建的,沒有就建一個類別標籤吧!!
image
(4)下載、安裝PickPack
(5)PickPack 也操他媽簡單,看一下這幾個圖妳就操他媽上手了。
image
image
(6)整個很方便、迅速啊。
Ctrl + C、Ctrl + V,圖就上好了,還可以自己加框、箭頭、文字
image

對了,很重要的一件事,po文很容易有公司機密(eg.source code),但為了要閃洩漏機密卻得另外精心po文搞一大堆替代文字,卻會因此而懶得po文,所以,請回覆討論這個部落格是開放為任何人皆可閱讀還是只有我們幾個人可以閱讀??
目前是”任何人皆可閱讀”。
我想,目前還是先做公開的好了,先看這個站大家反應如何再來決定下一步。

以IO的方式,掃瞄PCI bus device。(透過CF8、CFC port)

Dos debug32.com
-a
mov eax, 80000000  #bus0_dev0_fun0
mov dx, cf8  #IO port cf8(Index)
out dx, eax  #寫入eax的值到cf8這個port
mov dx, cfc  #IO port cfc(Data)
in eax, dx  #到cfc這個port去讀值,放到eax暫存器


image

  1. 準備一隻可開機至dos的隨身碟,
    裡面放好debug32.exe這隻檔案,
    不確定debug32.exe是不是免費的,版權自理,
    開機進入DOS,執行debug32.exe。
  2. 這是debug32的選項
    詳見小木偶的網頁
    -D, dump – dump記憶體內容
    -E, Edit – 編輯記憶體內容
    -A, Assembly - 寫簡單的組語
    -U, Un-assembly - 反組譯
    -R, Register - 看暫存器
    -T, Trace - 可以Trace指令(Instruction),單步等。
    -G, Go - 直接執行指令(Instruction)
    -S, Search – 在某段記憶體中,搜尋某字串or某值
    以上是我有用過的幾種選項,其他的就要另外再查。
    這裡要先用到-A,寫簡單的組語
  3. Segment: Offset,詳見小木偶的網頁
  4. 編輯組合語言,
    我們要到用到IN、OUT,詳見IN、OUT指令

    OUT 指令
    out      dx,al
    #out     輸出入埠編號,欲送至此埠的資料

    IN 指令
    in       al,dx
    #in      存放讀出來的資料,輸出入埠編號

    第1行—>mov eax, 80000000
    第2行—>mov dx, cf8
    第3行—>out dx, eax
  5. code只有5行, 主要目的是第3行的out這個動作, 透過IO port cf8,去偵測 Bus_0, Device_0, Function_0, 那為甚麼80000000h就是Bus_0, Dev0, Fun_0? 詳見PCI Bus spec。

  6. 第四行—>mov dx, cfc
    第五行—>in eax, dx
    其實就是這樣,
    去cfc把資料(Data)讀出來。
image

  1. -u 100
    反組譯,從offset 100的地方開始。
    如果打得是-u 10b,那就會從offset 10b的地方開始反組譯。
  2. 30D5: 0100 ~ 30D5: 010e,
    這幾行的記憶體位址,就是我們剛剛寫的code。
  3. 像第一行的mov指令,佔了6個Byte,(0100 ~ 0105)
    第二行的mov指令,佔了3個Byte,(0106 ~ 0108)
    …以此類推
image
  1. -r ip 0100
    主要目的是要執行我們剛剛寫的code,
    所以要寫入 ip 這個暫存器,0100的值,
    0100,就是我們的第一行指令。
    若像下一行一樣只單打一個 –r
    就是顯示目前暫存器的值。

    IP, Instruction Pointer, 指令指標,
    這個暫存器是一個指標,指向下一條指令。
  2. -t
    就是trace,目前就是單步執行。
image
可以看到執行了幾次單步之後,
我們最後一行從 port cfc in 回來的值會放在 AX 這個暫存器,
然後看得到 AX = 8086,
也就是 Bus_0, Dev_0, Fun_0 的 Vendor ID,
也就是 Intel。
如果要掃瞄整個PCI bus,
就把這幾行寫成一個迴圈,
只要掃回來的值不是 ffffh,
那就是有Device。

利用Dos的Debug指令,制作簡易的重開機執行檔--Reset.com

開到Dos然後輸入Debug
-a
jmp f000:fff0
按下Enter鍵結束。
看到剛剛輸入完後一共用了5個Byte,
所以要輸入size到cx暫存器,
-r cx
輸入0005
然後指定檔名,這裡取名為Reset.com
最後儲存。
-w
完成。

最大公因數 GCD

最大公因數(Greatest Common Divisor,簡寫為G.C.D.;或Highest Common Factor,簡寫為H.C.F.),指某幾個整數共有因數中最大的一個。
兩個整數的最大公因數主要有三種尋找方法:
參考來源:最大公因數 - 維基百科展轉相除法 - 維基百科

//
//還沒加入檢查輸入不可為float(浮點數)
//
#include <stdio.h>
#include <stdlib.h>

#define INT int
#define UINT unsigned int
#define STATUS
#define SUCCESS 0
#define ERROR_PARSE 1
#define ERROR_BUFFER 2
#define DEVISOR_FIRST_VALUE 1

//求出兩傳入值的最大公因數。
STATUS UINT
CaculateGcd(INT InputVariableA,INT InputVariableB,UINT *Result);

//
//輸入兩數,求最大公因數
//
int main(int argc, char *argv[]){
  INT InputVariableA;
  INT InputVariableB;
  UINT Result;
  UINT Status;

  InputVariableA = NULL;
  InputVariableB = NULL;
  Status = NULL;
  Result = DEVISOR_FIRST_VALUE;
 
  //等待按鍵輸入
  scanf("%d %d", &InputVariableA, &InputVariableB);
  printf("您輸入的數字為%d, %d\n", InputVariableA, InputVariableB);

  //呼叫副程式,求最大公因數,然後判斷Status。
  Status = CaculateGcd(InputVariableA, InputVariableB, &Result);
  switch(Status){
    case(SUCCESS):
      printf("%d與 %d的最大公因數為:%d\n", InputVariableA, InputVariableB, Result);
      break;
    case(ERROR_PARSE):
      printf("Error No. = %d,傳入值錯誤\n", ERROR_PARSE);
      break;
    case(ERROR_BUFFER):
      printf("Error No. = %d,Buffer錯誤\n", ERROR_BUFFER);
      break;
  }

  system("PAUSE");
  return 0;   
}

//求出兩傳入值的最大公因數。
STATUS UINT
CaculateGcd(INT InputVariableA, INT InputVariableB, UINT *Result){
  UINT Bigger;
  UINT Smaller;
  UINT Buffer;

  //檢查傳入值
  if(InputVariableA == NULL || InputVariableB == NULL || InputVariableA < 1 || InputVariableB < 1){
     return ERROR_PARSE;//不接受的傳入值
  }
  if(*Result != DEVISOR_FIRST_VALUE){
    return ERROR_BUFFER;//Buffer錯誤          
  }

  //(1)檢查兩數是否相等。
  if(InputVariableA == InputVariableB){
    *Result = InputVariableA;
    return SUCCESS;
  }

  //(2)檢查兩數之中,何為大數,何為小數。 
  if(InputVariableA > InputVariableB){
    Bigger = InputVariableA;
    Smaller = InputVariableB;                 
  } else{
    Bigger = InputVariableB;
    Smaller = InputVariableA;     
  }

  //(3)輾轉相除法
  do{
    Buffer = Bigger % Smaller;
    if(Buffer == 0){
      *Result = Smaller;
    } else {
      Bigger = Smaller;
      Smaller = Buffer;
    }
  } while(Buffer != 0);

  return SUCCESS;
}

檢視S3 喚醒,BIOS所花時間

Windows 7有此功能,Vista應該也有…
在S3喚醒後,"事件檢視器"->"Windows紀錄"->"系統"->"PowerTroubleShooter"->"詳細資料"->"BiosInitDuration"
可以看到S3喚醒,BIOS所花的時間。
一般要求在500~600(單位未查證,應該是ms,千分之一秒)
而有獨顯的機種S3喚醒時間會比較長。

IA-32處理器 - 基本操作模式

IA-32處理器有三個基本操作模式
- Protected Mode。(保護模式)
- Real-address Mode。(實體位址模式)
- System Mangement Mode; SMM。(系統管理模式)

另一種模式是 Vitual-8086 Mode (虛擬8086模式),它是保護模式的特殊情況。
—>在保護模式下的同時,處理器還可以在安全的多工環境中,直接執行 Real-address Mode 軟體,例如像是 MS-DOS 程式。換句話說,就算有一個 MS-DOS 程式當機,或者此程式要將資料寫入系統記憶體區域,也不會影響其他正在執行的程式。 Windows XP 可以同時執行多個各別的 Vitual-8086 session (對話)。
* 每個程式都可以擁有自己的 1 MB 記憶體區域。

(1) Protected Mode:
Protected Mode 是處理器最原始的狀態,在這種模式下,所有指令與功能都是可以使用的。此時程式會被分配得到各自的記憶體空間,此記憶體空間稱為 segments (區段),且處理器會防止程式referrence (參考) 被指派的 segments (區段) 以外的記憶體。

(2) Real-address Mode:
* Real-address Mode 可以實作出 Intel 8086 處理器的程式執行環境,而且所實作的環境還具有一些額外的功能,例如切換到其他模式的功能。Real-address Mode 可以在 Windows 98 中使用,而且可以用來執行一個須要直接存取系統記憶體或硬體裝置的 MS-DOS 程式。在Real-address Mode 下執行的程式,可能導致作業系統當機(無法再對使用者所下達的命令加以反應)。
* Real-address Mode 的程式,最多僅能存取 1 MB 的記憶體範圍

(3) Ssytem Management Mode; SMM:
SMM 提供作業系統額外的機制,用於增加像電源管理和系統安全等功能。電腦製造商為了特定的系統設定,會使用自訂的處理器,而且這些廠商通常也會實作上述的額外功能。

基本的程式執行暫存器

Register(暫存器):
Register是在CPU內部的高速儲存空間,它是設計用來以遠高於一般記憶體的速度進行存取的動作。例如,當處理中的迴圈必須在速度上有最佳化效果時,迴圈計數器會儲存於暫存器而不是在變數中。
Purpose
Although the main registers (with the exception of the instruction pointer) are "general-purpose" and can be used for anything, it was envisioned that they be used for the following purposes:
  • AX/EAX/RAX: accumulator
  • BX/EBX/RBX: base index (ex: arrays)
  • CX/ECX/RCX: counter
  • DX/EDX/RDX: data/general
  • SI/ESI/RSI: "source index" for string operations.
  • DI/EDI/RDI: "destination index" for string operations.
  • SP/ESP/RSP: stack pointer for top address of the stack.
  • BP/EBP/RBP: stack base pointer for holding the address of the current stack frame.
  • IP/EIP/RIP: instruction pointer. Holds the program counter, the current instruction address.
    引用來源:http://en.wikipedia.org/wiki/X86#x86_registers

Basic program execution registers(基本的程式執行暫存器):
- 8 個 General-Purpose Registers (通用暫存器)   
  EAX, EBX, ECX, EDX, EBP, ESP, ESI, EDI
- 6個 Segment Registers (區段暫存器)   
  CS, SS, DS, ES, FS, GS
- 1個 EFLAGS (用於儲存處理器狀態旗標的暫存器)
- 1個 EIP, Instruction Pointer (指令指標)


EBP, Base Pointer (基底指標),高階語言經常使用 EBP 來參照堆疊中的函數參數和局部變數 (local variable)。除非有高超的程式設計能否則不應將它用於平常的算術運算或資料搬移。因此,它通常稱為 Extended Frame Pointer Register (延伸框架指標暫存器)。

EAX, Extended Accumulator (延伸累加器),在執行乘法與法指令時,會自動使用 EAX 暫存器。
EBX, Base Index (ex: arrays)
ECX, Counter, CPU 會自動使用 ECX 當做迴圈計數器。
EDX, Data / General
ESP, Stack Pointer(堆疊指標), ESP 會用於定址在 Stack (堆疊)中的資料。
ESI, Extended Source Index (延伸來源索引)
EDI, Extended Destination Index (延伸目的索引)
ESI與EDI常用在高速的記憶體轉移指令。

Instruction Pointer(指令指標): 暫存器儲存著下一個即將執行的指令位址,有些特定的機器指令可以更動 EIP ,讓程式分支到新的位置去執行。

Segment Registers(區段暫存器): 在Real-Address Mode (實體位址模式)下, Segment Registers 用以定義 Segment 的 Base Address(基底位址), Segment 是預先指定的記憶體區域。在 Protected Mode 下, Segment Registers儲存的是”用於指向區段描述符表的指標”。有些 Segment 儲存的是程式指令(Code;程式碼),其他的 Segment 儲存的則是變數(Data;資料),另一種稱為 Stack Segment (堆疊區段)的區段,儲存的是局部變數以及函數參數。
CS, Code Segment
SS, Stack Segment
DS, Data Segment
ES, Extra Segment
FS, Flag Segment
GS, Global Segment
3.1-2 節區暫存器與指標暫存器


節區暫存器(segment register)又稱為段暫存器,在80386 CPU以下的規劃分別有CS、SS、DS、ES四個16位元的暫存器,386以後加入FS、GS兩個。規劃這些暫存器的主要目的是希望將主記憶體分成好幾個管理區域,分別可以指定給程式及不同目的的資料存放,例如CS就是規劃來指定給指令碼存放的區段,所以稱為指令段(code segment)暫存器,而SS為堆疊段(stack segment)暫存器,DS、ES分別為資料段(data segment) 及額外段(extra segment)暫存器,以及80386以後的CPU所加入的FS、GS分別為旗號段(flag segment) 及總體段(global segment)暫存器,這些段暫存器都可定義出特定資料存取的區段。

節區暫存器只關係著區段的粗略位址,80X86 CPU的實際位址必須仰賴節區暫存器有效位址共同的計算來決定(請參照圖3-1及圖3-4),計算的方法為:

實際位址 = 節區暫存器位址 × 16 + 有效位址


每一種節區暫存器在特定目的下必須配合一個特定的指標暫存器一起使用,而指標暫存器的內容往往就是有效位址的一部份或全部(請參考下一節定址法),例如指令段(CS)暫存器必須配合指令指標(IP)暫存器定義出指令的有效位址,因此:

指令實際位址 = 指令節區暫存器 × 16 + 指令指標暫存器

由於指令實際位址都由CPU的程式計數器(PC)來決定,因此80×86CPU的PC = CS × 16 + IP。此處的CS × 16,對於二進碼而言,只需將CS左移四個位元,再補上四個0即可。

另外,堆疊段(SS)暫存器也沒有其他的選擇,必須配合堆疊指標(SP)暫存器一起使用定義出堆疊資料存放的實際位址。而字串處理(搬移、搜尋、比較)指令中,字串來源的位址被定義在資料段(DS)暫存器與來源索引(SI)暫存器中,處理後存放的目標位址則被定義在額外段(ES)暫存器與目標索引(DI)暫存器中。至於基底指標暫存器(BP)與堆疊段(SS)暫存器合用時,才可以存取堆疊段的資料。以上這些段暫存器與其可配合的指標暫存器,簡記於下:

CS:IP        指令段:指令指標
SS:SP       堆疊段:堆疊指標
DS:SI        資料段:來源索引
ES:DI        額外段:目標索引
SS:BP       堆疊段:基底指標

在眾多型態的指標暫存器當中,它們的儲存值都是可以被指令所更改或讀取的,唯一不能被使用者更改或讀取者就是指令指標(IP)暫存器,它僅隨指令的進行自動指向指令的提取位址,所以有些書籍是將它歸類在特殊暫存器當中。

例3-1 某程式碼置於記憶體AC00h的指令段,80×86CPU目前正要提取有效位址為1234h的指令操作碼,請問此操作碼在記憶體中的實際位址。

解: CS=AC00h,IP=1234h,

則 實際位址= CS×16+IP=AC000h +1234h =AD234h

X86 定址模式 Addressing Mode 大全

引用來源:Frank's 資訊科技潮流站

Immediate Addressing Mode

這種表示法是最簡單的,完全不用去找位址,就直接把值給出來,給電腦去玩 (當然這樣程式比較沒有彈性)

例如 MOV AX,12h

就是直接把12這個值,丟到暫存器AX中

Register Operand Addressing Mode

這種表示法也沒有什麼位址可言,因為所指定的就是那個Register裡面的內容

例如 MOV AX,BX

就是純粹把 BX 裡面的資料移到 AX 中

Register Indirect Addressing Mode

這種表示法,就是把暫存器裡面的資料,變成一個位址來想

例如本來 BX 裡面放了 0123 這筆資料

用了 Register Indirect之後,就變成是指定 0123 這個位址

例如 MOV CX,[BX]

就是把記憶體位址 (DS)0 + BX 裡面的資料,移到 CX

至於為什麼是 (DS)0+BX..

based.GIF

因為,如果我們在組合語言程式裡面要求 BX (123) 位址的資料的時候

其實找到的是 (DS)0 + BX 位址的資料

因為上述的 BX  只是 Logical Address ,是寫程式方便用的

而 (DS)0 + BX 才是 Physical Address 才是實體真正操作的位址

PA = (DS)0 或 (CS)0 或 (SS)0 或 (ES)0  +  AX 或 BX 或 CX 或 DX


Based Addressing Mode

rbased.GIF

同上面那種方法,只是後面加了一個offset

寫成組合語言就像這樣

MOV CX,[BX]+0156h

而[BX]+0156h的實體記憶體位址是

(DS)0 + BX + 156

PA = (DS)0 或 (CS)0 或 (SS)0 或 (ES)0  +  AX 或 BX 或 CX 或 DX + offset


Based-Indexed Addressing Mode

basedindex.GIF

承上,只不過多了一個index值

組合語言寫法例 MOV CX,[BX+DI]+0156h

PA = (DS)0 或 (CS)0 或 (SS)0 或 (ES)0  +  AX 或 BX 或 CX 或 DX + SI 或 DI + offset

引用來源:X86 定址模式 Addressing Mode 大全

X86 CPU 暫存器 Register 大全

引用來源:Frank's 資訊科技潮流站

這是 Intel X86 架構下的 CPU 的所有暫存器 ( Register )

8088.JPG

首先,所有暫存器(Register)都只是一個長度為 16bit = 2byte = 1word 長度的一個空間

memblock.GIF

裡面存放 二進位 (Binary) 數字 , 負責記錄一筆數字資料 (最大值為65535)


01.JPG

CS = Code Segment,是指一個程式是從哪個位址開始

例如從000A,CS裡面就會記載000A

CS 通常會搭配 IP 使用,程式目前跑到的位置,就由 (CS)0 + IP 決定

如果跑到程式第一行,IP就是0,如果跑到第三行,IP就是2

那麼在實體記憶體實際上的位址就分別是 000A0 和 000A2

DS = Data Segment ,是指資料從記憶體的哪個位址開始

DS 通常會搭配其他暫存器使用,例如 BX、CX 等等

假如你在組合語言中要求使用 [BX] 這個位址的資料 ,而 BX = 3

那麼你其實找到的是在記憶體位置 (DS)0 + BX 位址的資料 ,即是000A3這個位址的資料   (假如DS=000A)

還是看不懂的,請來看看這篇吧~

SS = Stack Segment

這是表示你的堆疊( Stack )的底部位置

通常會搭配 SP 使用

SS + SP 就是目前 Stack 堆疊頂端的位址  (TOS,Top of Stack )

如果把一筆資料送入堆疊 ( PUSH ) ,那SP就會 -2

反之,若把一筆資料從堆疊中拿出 ( POP ) , 那SP就會 +2

(這裡的加減號並沒有打錯,如果有疑惑,請看這一篇)

ES = Extra Segment

這名符其實,是額外的Segment,大概可以靈活運用

不過若要賦值給它,則要注意

MOV ES,3H -> 這樣是錯的

MOV DX,3H
MOV ES,DX -> 這樣才可以


SI / DI 則分別代表

Source Index 和 Destination Index

(source=來源/Destination=目標)

舉個例子來講

組合語言指令中,MOV AX,BX

是將 BX 的資料複製到 AX

那麼,SI就要指向BX,DI就要指向AX


接下來的AX,BX,CX,DX

就是 General Purpose Registers (通用功能暫存器)

值得注意的是,這四個暫存器可以分成 High Bits 和 Low Bits 分別使用

例如 AX 可以拆成 AH 和 AL

memblock.GIF

當然,也可以自己就是一個暫存器使用

memblock.GIF

一般來說這四個暫存器可以隨時使用

但是這四個暫存器各自有特殊的功用

AX =Accumulator

例如在做乘法/除法的時候,AX暫存器就很特別

例如 MUL CX 這個指令

其實是把 CX 乘以 AX 的結果 放入 AX 之中

另外,發出I/O指令,也是由AX記載的內容決定要發出哪個指令

BX = Based

例如 XLAT指令,就是把  (DS)0 + AL + BX 的記憶體位址內容 丟到 AL 中

CX = Counter

Counter顧名思義是計數器,LOOP系列指令會對它產生影響

讓我們來看看以下這段程式碼

           MOV CX,5
AGAIN: NOP
           LOOPNZ AGAIN

( LOOPNZ = 若CX不為0就繼續 )

LOOPNZ這個指令是針對CX做變化,每跑到這個指令一次,就會把CX減去1
那麼,跑了5次之後,CX終於會扣到變成0,LOOP就結束

DX = Data

做一般資料傳輸用途。


Status Register (FLAGS)

這也是一個 16bit = 2byte = 1word 長度的 register

剛好每一個 bit 能放的就是 0 或 1

如果放 0 ,那個狀態,就是沒有 (reset)

放 1 就是有 (set)

以下是每一個 bit 分別代表的 flag (灰色代表保留未使用的)

flag.JPG

以下一一介紹

CF = Carry Flag = 進位

如果指令的運作中,使得資料產生了Carry,那麼CF就會變成 1 (set),反之就是 0 (reset)

例如 1000000000000000 + 1000000000000000 = 1 0000000000000000 

(注意,結果超出 1 位,紅色的1 已經跑到那筆資料的外面了,而那個 1 就是 carry)

carry.GIF

如果還是不太清楚的話

你只要把Carry當作是 16th bit 就可以了  (就是最左邊的那格,再往左延伸出去一格,變成從左往右數來第17格)

把整個記憶體位址當作有17個bit 去運算,如果 16th bit 是 1 ,那carry就是1,反之就是 0

ssss.GIF

(這也是為什麼發生進位和借位時,carry都是1)


PF = Parity Flag

看看計算的結果之中,存在幾個位數的「1」

如果是偶數個的話,PF=1,反之PF=0

舉例

00001010 => Parity Bit 為 1 (set)

00001000 => Parity Bit 為 0 (reset)


AF = Auxiliary Flag

相似CF,但這裡是以四個Bit為一組來做判斷的 ( 不過實際上只有偵測 4th bit 有沒有 進位carry 或 借位borrow )

auxx.GIF

像這張圖的情況,AF=1

這種四個bit一組的情況,就是在BCD的情況常用。


ZF = Zero Flag

如果計算出來的結果是 0 ,那麼 ZF=1 ,反之ZF=0

SF = Sign Flag

如果計算出來的結果有負號,那麼SF=1,反之SF=0

TF = Trap Flag

如果TF設定成1,那麼電腦的程式會逐行執行 (用於除錯等用途)

IF = Interrupt Flag

決定該CPU是否可以接受從外部發出的中斷請求

DF = Direction Flag

決定字串的讀取是由「高位讀到低位」(small endian)還是「低位讀到高位」(big endian)

X86的設計,預設是small endian

例如 在small endian

位址 00 資料為 34 ,位址 01 資料為 12

那麼這個字串讀起來就是 1234

(DF=0時,就是small endian)

OF = Overflow Flag

如果資料計算結果,產生溢位(overflow),OF=1,反之OF=0

OF = Overflow Flag

X86 CPU 堆疊概念

引用來源:Frank's 資訊科技潮流站

stack.GIF

這是 X86 CPU 的堆疊概念

不過很詭異的是,他的堆疊方法剛好是「倒過來的」

Stack的底端在最頭頂的Address,Stack的最上層居然是往下數的

這也就是為什麼

每增加一筆資料 (PUSH) 到堆疊中, SP反而要 減 2

每減少一筆資料 (POP ) SP 是 加 2

(是 2 而不是 1 的原因,是因為stack每一層都占2bytes)

另外,這個Stack的大小是固定的

就只有 FFFE 這麼大而已 (約64KB)

利用df指令,檢視磁碟分割區容量資訊。

終端機下輸入:
iii@iii-desktop:~$ df --help
用法:df [選項]... [檔案]...
顯示每個 <檔案> 所在的檔案系統的資訊,預設是顯示所有檔案系統。
長選項必須有的引數,短選項也必須有。
  -a, --all             include dummy file systems
  -B, --block-size=SIZE  use SIZE-byte blocks
      --total           produce a grand total
  -h, --human-readable  print sizes in human readable format (e.g., 1K 234M 2G)
  -H, --si              likewise, but use powers of 1000 not 1024
  -i, --inodes          顯示 inode 資訊而非區段使用量
  -k                    即 --block-size=1K
  -l, --local           只顯示本機的檔案系統
      --no-sync         取得使用量資料前不進行 sync 動作 (預設)
  -P, --portability     使用 POSIX 輸出格式
      --sync            取得使用量資料前先進行 sync 動作
  -t, --type=類型       只印出指定 <類型> 的檔案系統資訊
  -T, --print-type      印出檔案系統類型
  -x, --exclude-type=類型   只印出不是指定 <類型> 的檔案系統資訊
  -v                    (此選項不作處理)
      --help     顯示此求助說明並離開
      --version  顯示版本資訊並離開
<大小> 可以是以下的單位 (單位前可加上整數):
kB=1000,K=1024,MB=1000000,M=1048576,還有 G、T、P、E、Z、Y 如此類推。

利用mount指令,掛載iso檔,達成虛擬光碟的功能。

利用mount指令,掛載iso檔,達成虛擬光碟的功能。
以ubuntu 10.04為例:
[掛載] 在終端機輸入:
sudo mkdir /media/iso
sudo mount /media/Portable_H.D/brasero.iso /media/iso/ -t iso9660 -o loop,utf8
mount後先輸入PATH/*.iso,後輸入掛載到哪邊,utf8不打的話會中文亂碼。
[卸載]
sudo umount /media/iso