?? o語言匯編基礎教程.htm
字號:
<HTML>
<BODY LINK="#0000ff">
O語言網站http://www.olanguage.org/<br>
什么是O語言?<br>
O語言當前的版本是一門計算機匯編語言,它可以同時支持中文和英文,是當前唯一能支持非英文的計算機語言。本教程主要講述計算機指令運行機制及匯編語言的相關知識,并用詳實的例子來講解如何使用O匯編語言來編寫程序。匯編語言是計算機低級語言,它直接對應的是計算機機器指令,據有執行高效的特點,但由于它的底層性,指令浩繁復雜,如果你熟悉如MASM、FASM或者NASM等其它的匯編語言,那么你將能夠很容易地學會使用O語言,它的內部機制與其它匯編語言是一致的;如果你沒有接觸過匯編語言,那么本教程將為你打開計算機語言的大門,深入細致地解剖聰明的計算機大腦的思考軌跡。如果你使用過C或者其它的計算機語言將對學習O語言有一定的幫助。<br><br>
計算機大腦的結構<br>
如果你已經熟悉CPU的結構可以跳過本節,但還是建議你對本節做簡要的瀏覽,以熟悉O語言對寄存器的命名規則。計算機之所以能夠思考全依賴于一個叫做中央處理器(CPU)的芯片,隨著時代與科技的發展,處理器主要發展成為兩大類別,一類是基于RISC(Reduced Instruction Set Computer)即精簡指令系統架構的處理器,這類的處理器主要有以下幾種:PowerPC處理器、SPARC處理器、 PA-RISC處理器、MIPS處理器、Alpha處理器。另一類是基于CISC(Complex Instruction Set Computer)即復雜指令系統的處理器,這種類型的處理器被廣泛應用于個人電腦,也是人們最為熟悉的處理器,主要由Intel公司生產,所以又叫Intel架構的處理器,目前市場還有AMD公司和Cyrix公司與Intel競爭,讓中國人鼓舞的是由中國自主研發的微型處理器已經具有相當的處理能力。本文主要講述的就是針對這一類型處理器的指令系統,如無特殊說明,本文所說的處理器都指的是Intel架構的處理器,指令都是復雜指令系統的指令。即便是生產的公司與國別不同,處理器的思考方式是相似的,它們都能夠處理傳統的絕大部分指令,只是在效能上稍有不同。微型處理器的硬件結構決定了它的工作方式,它只能識別規定范圍內的指令和數據,我們要想讓它為我們工作除了尊重它的思維模式外沒有其他任何辦法,因此在研究計算機指令和學習計算機語言之前,有必要對這處理器的內部結構作一定的了解。首先來簡單地了解一下計算機的工作原理,下圖是現代微型計算機模型:<br><IMG src="computer_brain_strucutre_001.jpg"><br>
(圖1.1 微型計算機模型)<br><br>
這是典型的微機原理圖,我們主要討論中央處理部分,<br>
處理器(CPU)所有要處理的數據包括執行的二進制碼指令都存儲在主存儲器中,主存儲器就是我們常說的內存,處理器內部的控制器從內存中取得指令并執行,并根據指令的意義對數據進行運算,處理后的結果也存儲在內存中。處理器不僅要對數據進行運算,還要管理外圍的部件,控制它們有序地進行工作。于是相應地匯編指令中不僅有用于加減乘除這樣基本的數據運算指令,而且還有中斷這樣基本的控制指令。接下來讓我們進一步了解處理器管理數據的來龍去脈,下面是計算機模型數據通路結構圖:<br><IMG src="computer_brain_strucutre_002.jpg"><br>
(圖1.2 模型機數據通路結構)<br>
控制器是全機的指揮控制中心,其基本功能是執行指令,由微操作信號發生器根據指令產生控制信號序列以命令相應部件分布完成指定的工作;控制器既可以控制處理器內部的數據傳送,使累加器(ALU)完成指定功能和其他內部操作,也可以向處理器外部發出控制信號,控制處理器與存儲器或輸入輸出設備之間的數據傳送。微操作命令是最基本的控制信號,通常直接作用于部件或控制門電路的控制信號,簡稱微命令。這個圖有點復雜,搞不懂也沒關系,我們只要知道,處理器主要由控制器和運算器來執行指令和處理數據,而運算器又由累加器和寄存器組成,寄存器就是處理器用來內部存儲數據用的部件,在控制器的指令控制下,累加器可以從指定的寄存器中獲得數據并進行運算處理后返回結果到指定的寄存器中。<br><IMG src="computer_brain_strucutre_003.jpg"><br>
(圖1.3 處理器模型)<br>
對匯編程序而言,除了知道數目繁多的匯編指令名稱外,用得最多的就是寄存器,因此,我們必須對寄存器要有詳細的了解。在二十世紀九十年代,當時的處理器還只處于8086和80286時代,這種處理器的寄存器是16位的,它一條指令最多只能處理16位的數據,因此這種處理器也叫做16位處理器,而處理器與內存進行數據交互使用的地址線是20位;現在應用最廣泛的Intel公司生產的奔騰系統的處理器都是32位處理器,它內部的寄存器是32位,一條指令可以處理32位的數據,而且處理器與內存進行數據交互時的地址線也是32位的,關于處理器的內存尋址方式后面章節會進一步闡述。<br>
寄存器按功能可劃分為通用寄存器、指令指針寄存器和標志寄存器。O語言是中文語言,它對處理器內部的寄存器都進行了統一的中文命名,圖1.4是寄存器模型中,英文命名是標準的寄存器名,而中文是O語言使用的命名方式,寄存器中文命名的規則是寄存器功能加上位數識別,比如AX是16位累加器,中文名則是累加一六,而相應地32位累加器EAX則為累加三二,不區分大小的寄存器則直接使用功能名稱,這能夠很容易地記住各個寄存器的用途及大小。<br><IMG src="computer_brain_strucutre_004.jpg"><br>
注:著深綠色部分在386或更高處理器可用<br>
(圖1.4 80x86/Pentium處理器的寄存器模型)<br><br>
通用寄存器也稱多功能寄存器,共有八個通用寄存器,按它們的功能差別,又可分為兩組,即:“通用數據寄存器”及“指針寄存器和變址寄存器”。通用數據寄存器用來存放8位、16位或32位的操作數。大多數算術運算和邏輯運算指令都可以使用這些寄存器。共有4個通用數據寄存器,它們是累加寄存器、基址寄存器、計數寄存器和數據寄存器。另外4個通用寄存器,指針寄存器和變址寄存器主要是以不同的方式來訪問內存空間時用的寄存器,分別是:堆棧指針寄存器、基址指針寄存器、源變址寄存器和目的變址寄存器。<br>
程序是有序的指令集,但處理器執行時并不是以流水帳的形式一成不變地從指令開始執行到指令結束,而可能是從一個位置跳轉到另一位置跳躍式地執行,指令指針寄存器內保存的值下一條指令所在的內存位置,可以用跳轉、過程調用及中斷等指令來改變這個寄存器的值,這就控制了程序執行的路徑。<br>
標志寄存器的使用比較復雜,它內部的每一位都有特定的用途,用于指示微處理器的狀態并控制它的操作。圖1.5展示了80x86/Pentium系列所有型號微處理器的標志寄存器的情況。早期的8086/8088微處理器的標志寄存器FLAG為16位,且只定義了其中的9位;80286微處理器雖然仍為16位的標志寄存器,但定義的標志位已從原來的9位增加到12位(新增加了3個標志位); 80386及更高型號的微處理器則采用32位的標志寄存器EFLAGS,所定義的標志位也有相應的擴充。<br><br>
<IMG src="computer_brain_strucutre_005.jpg"><br>
(圖1.5 80x86/Pentium系列處理器的標志寄存器)<br><br><IMG src="computer_brain_strucutre_006.jpg"><br>
(圖1.6 8086/8088標志寄存器的格式及各位的功能)<br>
8086/8088系統中所定義的9個標志位:O、D、I、T、S、Z、A、P、C。在這9個標志位中,有6位(即CF、PF、AF、ZF、SF和OF)為狀態標志;其余3位(即TF、IF和DF)為控制標志。<br>
<B>狀態標志</B>反映微處理器的工作狀態,如執行加法運算時是否產生進位,執行減法運算時是否產生借位,運算結果是否為零等;<br>
<B>控制標志</B>對微處理器的運行起特定的控制作用,如以單步方式運行還是以連續方式運行,在程序執行過程中是否允許響應外部中斷請求等。<br>
六個狀態標志的功能簡述如下:<br>
(1) 進位標志CF(Carry Flag): 當執行算術運算指令時,其結果的最高位有進位或借位時將CF置1;否則將CF置0。<br>
(2) 奇偶標志PF(Parity Flag): 該標志位反映操作結果低8位中“1”的個數情況,若為偶數個“1”,則將PF置“1”;若為奇數個“1”,則將PF置“0”。它是早期Intel微處理器在數據通信環境中校驗數據的一種手段。今天,奇偶校驗通常由數據存儲和通信設備完成,而不是由微處理器完成。所以,這個標志位在現代程序設計中很少使用<br>
(3) 輔助進位標志AF(Auxiliary carry Flag):輔助進位標志也稱“半進位”標志。AF=1,表示本次運算的低4位中的最高位有進位(加法運算時)或有借位(減法運算時)。AF一般用于BCD運算中是否進行十進制調整的依據。十進制調整指令DAA和DAS測試這個標志位。<br>
(4) 零標志ZF(Zero Flag):反映運算結果是否為零。若結果為零,則ZF=1;若結果不為零,則ZF=0。<br>
(5) 符號標志SF(Sign Flag):反映帶符號數(以二進制補碼表示)運算結果符號位的情況。若結果為負數,則SF=1;若結果為正數,則SF=0。SF的取值總是與運算結果的最高位(字節操作為D7,字操作為D15,雙字操作為D31)取值一致。<br>
(6) 溢出標志OF(Overflow Flag):反映有符號數運算結果是否發生溢出。若發生溢出,則OF=1;否則,OF=0。所謂溢出,是指運算結果超出了計算裝置所能表示的數值范圍。例如,對于字節運算,數值表示范圍為-128~+127;對于字運算,數值表示范圍為-32768~+32767。若超過上述范圍,則發生了溢出。溢出是一種差錯,系統應做相應的處理。<br>
三個控制標志的功能:<br>
(1) 方向標志DF(Direction Flag):用來控制串操作指令的執行。若DF=0,則串操作指令的地址自動增量修改,串數據的傳送過程是從低地址到高地址的方向進行;若DF=1,則串操作指令的地址自動減量修改,串數據的傳送過程是從高地址到低地址的方向進行。可以設置DF的指令為STD(置1)和CLD(清0)。<br>
(2) 中斷標志IF(Interrupt Flag):用來控制對可屏蔽中斷的響應。若IF=1,則允許CPU響應可屏蔽中斷請求;若IF=0,則CPU不能對可屏蔽中斷請求作出響應。可以設置IF的指令有STI(置1)和CLI(置0)。IF對非屏蔽中斷和內部中斷不起作用。<br>
(3) 陷阱標志TF(Trap Flag):陷阱標志也稱單步標志。當TF=1時,微處理器就進入單步工作方式,每執行完一條指令便自動產生一個內部中斷(稱為單步中斷),轉去執行一個中斷服務程序,可以借助中斷服務程序來檢查每條指令的執行情況;若TF=0,則CPU正常(連續)執行指令。單步工作方式常用于程序的調試。<br>
指令指針寄存器與標志寄存器的功能是專用的,保存著重要的信息,因此也稱它們為專用寄存器。<br>
程序不僅有指令而且還有數據,為了便于管理和使用,將指令和數據分開以片段的形式存儲在內存的不同位置,內存地址是連續的,當指令對數據進行操作時就必須能夠很容易地定位到數據所在的內存地址,這時就要用到段寄存器,段寄存器內保存著某一段屬性相同數據的內存首地址,訪問內存數據都以這個首地址作為參照加上偏移量來得到數據的地址。這是簡單的內存數據管理模型,內存是處理器活動的主要場所,內存資源是最為寶貴的系統資源,實際對內存空間分配和使用的管理異常復雜,主要由操作系統來完成。下面簡單介紹各個段寄存器的功能:<br>
(1) 代碼段寄存器CS(Code Segment):代碼段顧名思義就是用來存儲指令代碼的一段內存區域,用以保存微處理器使用的代碼(程序或過程)。代碼段寄存器定義代碼段的起始地址。<br>
(2)數據段寄存器DS(Data Segment):數據段是包含程序所使用的大部分數據的存儲區。與代碼段寄存器CS類似,數據段寄存器用以定義數據段的起始地址。<br>
(3)附加段寄存器ES(Extra Segment):附加段是為某些串操作指令存放目的操作數而附加的一個數據段。附加段寄存器用以定義附加段的起始地址。<br>
(4)堆棧段寄存器SS(Stack Segment):堆棧是存儲器中的一個特殊存儲區,用以暫時存放程序運行中的一些數據和地址信息。堆棧段寄存器定義堆棧段的首地址。由堆棧段寄存器和堆棧指針寄存器確定堆棧段內的存取地址。另外,基址一六/基址三二寄存器也可以尋址堆棧段內的數據。<br>
(5)標志段FS和全局段GS寄存器:這兩個段寄存器僅對80386及更高型號的微處理器有效,以便程序訪問相應的兩個附加的存儲器段。<br>
小結:這一小節主要介紹了處理器的概貌,并著重講解了處理器內部寄存器的種類及功能,處理器的工作原理并不復雜,但是它的制造工藝隨著技術的發展,其硬件構造的復雜程度已經超過其它任何產品。學習O語言你不需要對處理器內部結構有很深的了解,但必須熟練掌握各種寄存器的名稱及功能。如果你是匯編的初學者,上面介紹的寄存器及功能可能并不容易理解,在后面用實例講述O語言使用時,你將能更直觀地感受到它們的用途及使用方法,在這里要求你對它們應留下大致的映像。<br><br>
寄存器對照表<br>
寄存器中文-英文命名對照表<br>
<TABLE BORDER CELLSPACING=1 CELLPADDING=7 WIDTH=494>
<TR><TD WIDTH="12%" VALIGN="TOP">
類型</TD>
<TD WIDTH="22%" VALIGN="MIDDLE">
中文名稱</TD>
<TD WIDTH="16%" VALIGN="MIDDLE">
英文名稱</TD>
<TD WIDTH="16%" VALIGN="TOP">
二進制碼</TD>
<TD WIDTH="34%" VALIGN="MIDDLE">
寄存器說明</TD>
</TR>
<TR><TD WIDTH="12%" VALIGN="TOP" ROWSPAN=16>
多 功 能 寄 存 器</TD>
<TD WIDTH="22%" VALIGN="MIDDLE">
累加低八</TD>
<TD WIDTH="16%" VALIGN="MIDDLE">
AL</TD>
<TD WIDTH="16%" VALIGN="TOP">
000</TD>
<TD WIDTH="34%" VALIGN="TOP">
累加寄存器低八位</TD>
</TR>
<TR><TD WIDTH="22%" VALIGN="MIDDLE">
累加高八</TD>
<TD WIDTH="16%" VALIGN="MIDDLE">
AH</TD>
<TD WIDTH="16%" VALIGN="TOP">
100</TD>
<TD WIDTH="34%" VALIGN="TOP">
累加寄存器低八位</TD>
</TR>
<TR><TD WIDTH="22%" VALIGN="MIDDLE">
累加一六</TD>
<TD WIDTH="16%" VALIGN="MIDDLE">
AX</TD>
<TD WIDTH="16%" VALIGN="TOP">
000</TD>
<TD WIDTH="34%" VALIGN="TOP">
16位累加寄存器</TD>
</TR>
<TR><TD WIDTH="22%" VALIGN="MIDDLE">
累加三二</TD>
<TD WIDTH="16%" VALIGN="MIDDLE">
EAX</TD>
<TD WIDTH="16%" VALIGN="TOP">
000</TD>
<TD WIDTH="34%" VALIGN="TOP">
32位累加寄存器</TD>
</TR>
<TR><TD WIDTH="22%" VALIGN="MIDDLE">
基址低八</TD>
<TD WIDTH="16%" VALIGN="MIDDLE">
BL</TD>
<TD WIDTH="16%" VALIGN="TOP">
011</TD>
<TD WIDTH="34%" VALIGN="TOP">
基址寄存器低八位</TD>
</TR>
<TR><TD WIDTH="22%" VALIGN="MIDDLE">
基址高八</TD>
<TD WIDTH="16%" VALIGN="MIDDLE">
BH</TD>
<TD WIDTH="16%" VALIGN="TOP">
111</TD>
<TD WIDTH="34%" VALIGN="TOP">
基址寄存器低八位</TD>
</TR>
<TR><TD WIDTH="22%" VALIGN="MIDDLE">
基址一六</TD>
<TD WIDTH="16%" VALIGN="MIDDLE">
BX</TD>
<TD WIDTH="16%" VALIGN="TOP">
011</TD>
<TD WIDTH="34%" VALIGN="TOP">
16位基址寄存器</TD>
</TR>
<TR><TD WIDTH="22%" VALIGN="MIDDLE">
基址三二</TD>
<TD WIDTH="16%" VALIGN="MIDDLE">
EBX</TD>
<TD WIDTH="16%" VALIGN="TOP">
011</TD>
<TD WIDTH="34%" VALIGN="TOP">
32位基址寄存器</TD>
</TR>
<TR><TD WIDTH="22%" VALIGN="MIDDLE">
計數低八</TD>
<TD WIDTH="16%" VALIGN="MIDDLE">
CL</TD>
<TD WIDTH="16%" VALIGN="TOP">
001</TD>
<TD WIDTH="34%" VALIGN="TOP">
計數寄存器低八位</TD>
</TR>
<TR><TD WIDTH="22%" VALIGN="MIDDLE">
計數高八</TD>
<TD WIDTH="16%" VALIGN="MIDDLE">
CH</TD>
<TD WIDTH="16%" VALIGN="TOP">
101</TD>
<TD WIDTH="34%" VALIGN="TOP">
計數寄存器低八位</TD>
</TR>
<TR><TD WIDTH="22%" VALIGN="MIDDLE">
計數一六</TD>
<TD WIDTH="16%" VALIGN="MIDDLE">
CX</TD>
<TD WIDTH="16%" VALIGN="TOP">
001</TD>
<TD WIDTH="34%" VALIGN="TOP">
16位計數寄存器</TD>
</TR>
<TR><TD WIDTH="22%" VALIGN="MIDDLE">
計數三二</TD>
<TD WIDTH="16%" VALIGN="MIDDLE">
ECX</TD>
<TD WIDTH="16%" VALIGN="TOP">
001</TD>
<TD WIDTH="34%" VALIGN="TOP">
32位計數寄存器</TD>
</TR>
<TR><TD WIDTH="22%" VALIGN="MIDDLE">
數據低八</TD>
<TD WIDTH="16%" VALIGN="MIDDLE">
DL</TD>
<TD WIDTH="16%" VALIGN="TOP">
010</TD>
<TD WIDTH="34%" VALIGN="TOP">
數據寄存器低八位</TD>
</TR>
<TR><TD WIDTH="22%" VALIGN="MIDDLE">
數據高八</TD>
<TD WIDTH="16%" VALIGN="MIDDLE">
DH</TD>
<TD WIDTH="16%" VALIGN="TOP">
110</TD>
<TD WIDTH="34%" VALIGN="TOP">
數據寄存器低八位</TD>
</TR>
<TR><TD WIDTH="22%" VALIGN="MIDDLE">
數據一六</TD>
<TD WIDTH="16%" VALIGN="MIDDLE">
DX</TD>
<TD WIDTH="16%" VALIGN="TOP">
010</TD>
<TD WIDTH="34%" VALIGN="TOP">
16位數據寄存器</TD>
</TR>
<TR><TD WIDTH="22%" VALIGN="MIDDLE">
數據三二</TD>
<TD WIDTH="16%" VALIGN="MIDDLE">
EDX</TD>
<TD WIDTH="16%" VALIGN="TOP">
010</TD>
<TD WIDTH="34%" VALIGN="TOP">
32位數據寄存器</TD>
</TR>
<TR><TD WIDTH="12%" VALIGN="TOP">
類型</TD>
<TD WIDTH="22%" VALIGN="MIDDLE">
中文名稱</TD>
<TD WIDTH="16%" VALIGN="MIDDLE">
英文名稱</TD>
<TD WIDTH="16%" VALIGN="TOP">
二進制碼</TD>
<TD WIDTH="34%" VALIGN="MIDDLE">
寄存器說明</TD>
</TR>
<TR><TD WIDTH="12%" VALIGN="MIDDLE" ROWSPAN=4>
指針寄存器</TD>
<TD WIDTH="22%" VALIGN="MIDDLE">
堆棧指針一六</TD>
<TD WIDTH="16%" VALIGN="MIDDLE">
SP</TD>
<TD WIDTH="16%" VALIGN="TOP">
100</TD>
<TD WIDTH="34%" VALIGN="TOP">
16位堆棧指針寄存器</TD>
</TR>
<TR><TD WIDTH="22%" VALIGN="MIDDLE">
堆棧指針三二</TD>
<TD WIDTH="16%" VALIGN="MIDDLE">
ESP</TD>
<TD WIDTH="16%" VALIGN="TOP">
100</TD>
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -