Win32

1、什麼是Win32?

 Win32是指你現在所使用的操作系統是32位的windows環境

Win32的重要意義?

  從單進程單線程到多進程多線程是操作系統發展的一種必然趨勢,當年的DOS系統屬於單任務操作系統,最優秀的程序員也只能通過駐留內存的方式實現所謂的"多任務",而如今的Win32操作系統卻可以一邊聽音樂,一邊編程,一邊打印文檔。
  理解多線程及其同步、互斥等通信方式是理解現代操作系統的關鍵一環,當我們精通了Win32多線程程序設計後,理解和學習其它操作系統的多任務控制也非常容易。許多程序員從來沒有學習過嵌入式系統領域著名的操作系統VxWorks,但是立馬就能在上面做開發,大概要歸功於平時在Win32多線程上下的功夫。
  因此,學習Win32多線程不僅對理解Win32本身有重要意義,而且對學習和領會其它操作系統也有觸類旁通的作用
進程(Process)是具有一定獨立功能的程序關於某個數據集合上的一次運行活動,是系統進行資源分配和調度的一個獨立單位。程序只是一組指令的有序集合,它本身沒有任何運行的含義,只是一個靜態實體。而進程則不同,它是程序在某個數據集上的執行,是一個動態實體。它因創建而產生,因調度而運行,因等待資源或事件而被處於等待狀態,因完成任務而被撤消,反映了一個程序在一定的數據集上運行的全部動態過程。
  線程(Thread)是進程的一個實體,是CPU調度和分派的基本單位。線程不能夠獨立執行,必須依存在應用程序中,由應用程序提供多個線程執行控制。

二者關係

  線程和進程的關係是:線程是屬於進程的,線程運行在進程空間內,同一進程所產生的線程共享同一內存空間,當進程退出時該進程所產生的線程都會被強制退出並清除。線程可與屬於同一進程的其它線程共享進程所擁有的全部資源,但是其本身基本上不擁有系統資源,只擁有一點在運行中必不可少的信息(如程序計數器、一組寄存器和棧)。

操作系統分類

  根據進程與線程的設置,操作系統大致分爲如下類型:
  (1)單進程、單線程,MS-DOS就是這種操作系統;
  (2)多進程、單線程,多數UNIX(及類UNIX的LINUX)是這種操作系統;
  (3)多進程、多線程,Win32(Windows NT/2000/XP等)、Solaris 2.x和OS/2都是這種操作系統;
  (4)單進程、多線程,VxWorks是這種操作系統。

引入線程的好處

  在操作系統中引入線程帶來的主要好處有:
  (1)通過進程來創建、終止線程比單獨地通過應用程序來創建、終止線程要快;
  (2)同一進程內的線程間切換比進程間的切換要快,尤其是用戶級線程間的切換。另外,線程的出現還有以下幾個原因:
  ①併發程序的併發執行,在多處理環境下更爲有效。一個併發程序可以建立一個進程,而這個併發程序中的若干併發程序段就可以分別建立若干線程,使這些線程在不同的處理機上執行。
  ②每個進程具有獨立的地址空間,而該進程內的所有線程共享該地址空間。這樣可以解決父子進程模型中,子進程必須複製父進程地址空間的問題。
  ③線程對解決客戶/服務器模型非常有效。

Dos彙編的特點

  在Dos下編彙編程序,我們可以管理系統的所有資源,我們可以改動系統中所有的內存,如自己改動內存控制塊來分配內存,自己修改中斷向量表來截獲中斷等,對其他操作也是如此,如我們對鍵盤端口直接操作就可以把鍵盤屏蔽掉,可以這樣來描述Dos系統:系統只有一個特權級別,在編程上講,任何程序和操作系統都是同級的,所以在Dos下,一個編得不好的程序會影響其他所有的程序,如一個程序把鍵盤口中斷關掉了,所有程序就都不能從鍵盤獲得鍵入的數據,直到任何一個程序重新打開鍵盤爲止,一個程序陷入死循環,也沒有其他程序可以把它終止掉。Dos下的編程思路是“單任務”的,你只要認爲你的程序會按照你的流程一步步的執行下去,不必考慮先後問題(當然程序可能會被中斷打斷,但你可以認爲它們會把環境恢復,如果中斷程序沒有把環境恢復,那是他們的錯)。

內存管理方式上的不同

  在內存管理方式上,Dos彙編和Win32彙編也有很多的不同:Dos工作在實模式下,我們可以尋址1M的內存,尋址時通過段寄存器來制定段的初始地址,每個段的大小爲64K,超過1M的部分,就只能把他作爲XMS使用,也就是說,只能用作數據存放使用而無法在其中執行程序。
  而Windows在保護模式下執行,這裏所有的資源對應用程序來說都是被“保護”的:程序在執行中有級別之分,只有操作系統工作在最高級--0級中,所有應用程序都工作在3級中(Ring3), 在Ring3中,你無法直接訪問IO端口,無法訪問其他程序運行的內存,連向程序自己的代碼段寫入數據都是非法的,會在Windows的屏幕上冒出一個熟悉的藍屏幕來。只有對Ring0的程序來說,系統纔是全開放的。

內存的不同

  在內存方面,Windows使用了處理器的分頁機制,使得對應用程序來說,所有的內存都是“平坦”的,你不必用一個段寄存器去指定段的地址,因爲在保護模式下,段寄存器的含義是不同的(可以參見80386手冊方面的書籍),你可以直接指定一個32位的地址來尋址4GB的內存。

程序結構方面的不同

  在程序結構方面,Windows程序也有很大的不同,它是“基於消息”的,你可以想象這樣一個常見的Windows窗口,上面有幾個按鈕,如果你用Dos編程的思路去考慮,你會發現實現它很困難:鼠標移動到窗口邊緣時拖動會改變窗口大小,鼠標點擊按鈕時再做要做的事,你會發現,你的程序自開始執行後就在等待,你不知道鼠標先會點什麼地方,實際上你是在等待所有可能的事情的發生。而在Dos下,你可以只顧自己先執行,需要用戶輸入時,再停下來,你不輸入我就不再執行,而且,我讓你輸入數據A你就不能輸入數據B。
  以上是Win32編程的基礎,無論對Win32彙編還是VC++,它們都是一樣的,下面我們來看看有關Win32彙編的內容。

編輯本段Win32ASM編譯器

  Win32ASM的編譯器最常用的有兩種:Borland公司的Tasm5.0和Microsoft的Masm6.11以上版本,兩種編譯器各有自己的優缺點,Tasm帶了一個不大不小的Import庫,而Masm沒有帶,但Masm在代碼的優化上面好象比Tasm做得好,但它卻不帶Import庫。看來使用哪一種編譯器還是比較難選擇的,但Steve Hutchesson給了我們一個答案,他爲Masm建立了一個很全的Import庫,基本上包括了Windows絕大部分的Api函數,這些庫、include文件和其他工具還有Masm6.14版本一起做成了一個 Masm32編譯器 -- Masm32V5。這樣一來,我們用匯編編程就象用C一樣方便。
  因爲有了Masm32V5,所以就我個人而言,我推薦使用Masm作爲Win32ASM的編譯工具,但Masm和Tasm的宏語法有很多的不同,我的這個教程是以Masm格式寫的。

編輯本段Masm32的環境設置

  在Win32編程中,由於Windows有很多的數據結構和定義,這些都放在include文件中,還有連接時要用到Import庫(通俗的講就是Windows提供的DLL文件中的函數列表,也就是告訴程序到哪裏去調用API函數),這些都放在include 和lib目錄中。我們在編譯時要指定以下的系統環境:
  set include=\Masm32v5\Include
  set lib=\Masmv5\lib
  set path=\Masmv5\Bin
  這樣編譯器就會到正確的路徑中去找 include 文件和 lib 文件。你可以自己在 autoexec.bat 文件中加上以上語句,爲了產生Windows的PE格式的執行文件,在編譯和連接中要指定相應的參數:
  編譯: Ml /c /coff 文件名.asm
  連接: Link /SUBSYSTEM:WINDOWS OBJ文件名.obj 資源文件名.res
  爲了不在每次編譯時都要打這麼多的參數,我們可以用 nmake 文件來代爲執行,nmake 是代碼維護程序,他會檢查 .asm .obj .exe .res 等文件的時間,如果你更新了源程序,他會自動執行編譯程序或連接程序產生相應的文件。你可以在文件名爲 makefile 的文件中指定使用的編譯器和連接程序以及相應的參數,下面是一個 makefile 文件的例子:
  NAME = Clock
  OBJS = $(NAME).obj
  RES = $(NAME).res
  $(NAME).exe: $(OBJS) $(RES)
  Link /DEBUG /SUBSYSTEM:WINDOWS $(OBJS) $(RES)
  $(RES): $(NAME).rc
  Rc $(NAME).rc
  .asm.obj:
  Ml /c /coff $(NAME).asm
  文件告訴 nmake程序,程序名爲 clock,產生 clock.exe 文件需要 clock.obj和 clock.res 文件,而產生 clock.res 文件需要 clock.rc 文件,產生 clock.obj 文件要用到 clock.asm 文件,至於是否需要執行 ml, link 和 rc,程序會根據文件的時間自動判斷。

編輯本段Win32ASM程序的結構和語法

  讓我們先來看看一個最簡單的Win32彙編程序:
  .386
  .model flat, stdcall
  option casemap :none ; case sensitive
  include windows.inc
  include kernel32.inc
  includelib kernel32.lib
  .data
  szCaption db 'Win32彙編例子',0
  szText db 'Win32彙編,Simple and powerful!',0
  .code
  start:
  invoke MessageBox,NULL,addr szText,addr szCaption,MB_OK
  invoke ExitProcess,NULL
  end start
  這就是一個能執行的最簡單的Win32彙編程序,下面我簡單地介紹一下各部分的作用:

386

  這條語句和Dos下彙編是一樣的,是告訴編譯器我們要用到80386的指令集,因爲32位彙編程序要用到32位的寄存器如eax,ebx等,所以這一句是必須的,當然,你也可以用.486,.586等,當用到特權指令時,還可以用 .386p,.486p等等。

include 語句

  include 語句包含了一些系統的定義和API函說明,其中所有的Windows 數據結構定義和常量定義包含在 windows.inc 中,而其他 API函數的說明包含在 xxx.inc 中, 如查 Microsoft Win32 Programmer's Reference 知道 ExitProcess包含在kernel32.dll 中,那麼我們就要在程序中包括 include kernel32.inc 和 includelib kernel32.lib語句,否則在編譯時會出現 API 函數未定義的錯誤。而 MessageBox 在 user32.dll 中,那麼我們就要在程序中包括 include user32.inc 和 includelib user32.lib語句

data 或data

  指明瞭接下來是數據段,.data 定義了預定義的變量,.data?定義了未初始化的變量,兩者的不同之處是 .data? 定義的變量並不佔用 .exe 文件的大小,而是在程序執行時動態分配,所以開始是不指定初始值的數據可以放在 .data? 段中,如一個1K大小的緩衝區,放在 .data?中,程序將不會增加一個字節。

code

  指明瞭接下來是代碼段,我們的所有代碼都放在這裏。最後的一句 start 語句指定了程序開始執行的語句。程序中的 ExitProcess 是一個標準的 Win32 API,對應 Dos彙編中的 int 20h 或 mov ah,4ch/int 21h,也就是程序退出。而 MessageBox 也是一個標準的 API,功能是在屏幕上顯示一個消息框,具體的參數上面已經解釋過了還有要注意的是 invoke MessageBox,NULL,addr szText,addr szCaption,MB_OK 語句中, MB_OK 和 NULL 已經預定義在 Windows.inc 中。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章