Jack’s第一個Win32組譯工具HelloWorld

來源:互聯網
上載者:User

本文已被更新,請看新版文章
Jack整理的Win32彙編基礎知識
http://blog.csdn.net/magus_yang/archive/2007/04/05/1552930.aspx

標 題: Jack's第一個Win32組譯工具HelloWorld

作 者: Jack Yang時 間: 2007-02-26 1:02鏈 接: http://blog.csdn.net/magus_yang/archive/2007/02/26/1514439.aspxHello.asm檔案的內容如下:;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>; 第一部分:模式和來源程式格式的定義語句              .386                                    ; 指令集              .model flat,stdcall                 ; 工作模式              option casemap:none             ; 格式;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>; Include 檔案定義;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>include           windows.incinclude           user32.incincludelib        user32.libinclude           kernel32.incincludelib        kernel32.lib;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>; 資料區段;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>              .dataszCaption       db    'A MessageBox !',0szText            db    'Hello, World !',0;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>; 程式碼片段;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>              .codestart:              invoke     MessageBox,NULL,offset szText,offset szCaption,MB_OK              invoke     ExitProcess,NULL;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>              end start        ; 指定程式的入口  1.         第一部分 模式和來源程式格式的定義語句第一行 指定使用的指令集(編譯器使用)Win32環境工作在80386及以上的處理器中,所以必須定義.386。如果程式(VxD等驅動程式)中要用到特權指令,那麼必須定義.386p。第二行 定義程式工作的模式(包括記憶體模式、語言模式、其它模式)對Win32程式來說,只有一種記憶體模式,即flat(平坦)模式。Win32 API調用使用的是stdcall格式,所以Win32彙編中必須在.model中加上stdcall參數。第三行 option語句       由於Win32 API中的API名稱區分大小寫,所以必須定義option casemap:none,來表明程式中的變數和子程式名對大小寫敏感。  2.         包含全部段的來源程式結構:.386.model flat,stdcalloption casemap:none<一些include語句>.stack [堆棧段的大小].data<一些初始化過的變數定義>.data?<一些沒有初始化過的變數定義>.const<一些常量定義>.code<代碼><開始標記><其他語句>end 開始標記  3.         段的定義資料區段       .data              已初始化資料區段,可讀可寫的已定義變數;當程式裝入完成時,這些值就已經在記憶體中;              資料定義在.data段中會增加可執行檔的大小;              .data段一般存放在可執行檔的_DATA節區(Section)內;       .data?              未初始化資料區段,可讀可寫的未定義變數,在可執行檔中不佔空間;              這些變數一般作為緩衝區或者在程式執行後才開始使用。              資料定義在.data?資料區段中不會增加可執行檔的大小;              .data?段一般存放在可執行檔的_BSS節區內;       .const              常量,可讀不可寫的變數; 程式碼片段       .code              所有的指令都必須寫在程式碼片段中;              Win32中,資料區段是不可執行檔,只有程式碼片段有可執行檔屬性;              對於運行在特權級3的應用程式,.code段不可寫。除非把可執行檔PE頭部中的屬性位改成可寫;              對於運行在特權級0的程式,所有的段都有讀寫權限,包括程式碼片段;              .code程式碼片段一般存放在可執行檔的_TEXT節區內; 堆棧段       .stack              與DOS彙編不同,Win32彙編不必考慮堆棧。系統會自動分配堆棧空間;              堆棧段的記憶體屬性是可讀寫並且可執行;              靠動態修改代碼的反跟蹤模組可以拷貝到堆棧中去邊修改邊執行;              緩衝區溢位技術也會用到這個特性;  4.         叫用作業系統功能的方法:DOS下作業系統的功能通過各種非強制中斷來實現。       應用程式叫用作業系統功能將經曆如下三個過程:              把相應的參數放在各個寄存器中再調用相應的中斷;              程式控制權轉到中斷中去執行;              完成以後通過iret中斷返回指令回到應用程式中;       DOS下調用系統功能方法的缺點:              所有的功能號定義是難以記憶的數字;              80x86系列處理器能處理的中斷最多隻能有256個;              通過寄存器來傳遞參數,對於參數較多的函數很不方便;Win32下       系統功能模組放在Windows的動態連結程式庫(DLL)中       作為Win32 API核心的3個DLL:              KERNEL32.DLL    系統服務功能。              GDI32.DLL           圖形裝置介面。              USER32.DLL         使用者介面服務。 常用API的參數和函式宣告,查看文檔《Microsoft Win32 Programmer's Reference》  5.         Win32 API 的函數原型聲明函數原型聲明的彙編格式如下:函數名 proto [距離] [語言] [參數1]:資料類型, [參數2]:資料類型,......proto是函式宣告的偽指令距離可以設定為NEAR、FAR、NEAR16、NEAR32、FAR16或FAR32,由於Win32中只有一個平坦的段,無所謂距離,所以在定義時可以忽略距離。語言類型可是使用.model所定義的預設值。 以訊息對話方塊函數MessageBox為例C格式如下:int MessageBox(       HWND hWnd,              // Handle to owner window       LPCTSTR lpText,         // text in message box       LPCTSTR lpCaption,     // message box title       UINT uType                 // message box style       ); 彙編格式如下:MessageBox Proto hWnd:dword,lpText:dword,lpCaption:dword,uType:dword或者寫為MessageBox Proto :dword,:dword,:dword,:dword編譯器只對參數的數量和類型感興趣,參數的名稱只是增加可讀性,所以可以省略。對於組合語言來說,Win32環境中的參數實際上只有一種類型,就是一個32位的整數(dword,double word),雙字,四位元組。   6.         調用Win32 API調用API有如下兩種方法:1)        invoke              MASM提供的偽指令;              invoke偽指令的好處就是能夠提高代碼的可讀性,減少錯誤;              invoke做了下面三件事:                     在編譯的時候,由編譯器把invoke偽指令展開成相應的push指令和call指令;                     進行參數數量的檢查工作;                     如果帶的參數數量和聲明時的數量不符,編譯器會報錯;2)        push和call的組合80386處理器的指令 invoke     MessageBox,NULL,offset szText,offset szCaption,MB_OK也可寫為push NULLpush offset szTextpush offset szCaptionpush MB_OKcall MessageBox  7.         Win32 API 函數傳回值的處理方法對於組合語言來說,Win32 API函數傳回值的類型只有dword一種類型,它永遠放在eax中。如果要返回的內容在一個eax中放不下,Win32 API採用如下方法來解決:a)         一般是eax中返回一個指向返回資料的指標;b)        在調用參數中提供一個緩衝區地址,資料直接返回到這個緩衝區中去。類似變參的概念;  8.         與字串相關Win32 API 的分類在Win32環境中,根據兩個不同的字元集(ANSI字元集和Unicode字元集),可以把和字串相關的API分成兩類:a)         處理ANSI字元集的Win32 API函數函數名稱的尾部帶一個“A”字元;ANSI字串是以NULL結尾的一串字元數組,每一個ANSI字元佔一個位元組的寬度;MessageBoxA Proto hWnd:dword,lpText:dword,lpCaption:dword,uType:dwordb)        處理Unicode字元集的Win32 API函數函數名稱的尾部帶一個“W”字元;              每一個Unicode字元佔兩個位元組的寬度,所以可以同時定義65536個不同的字元;              MessageBoxW Proto hWnd:dword,lpText:dword,lpCaption:dword,uType:dword Windows 9x系列不支援Unicode版本的API,絕大多數的API只有ANSI版本。只有Windows NT系列才完全支援Unicode版本的API。為了編寫在幾個平台中都能通用的程式,一般應用程式都使用ANSI版本的API函數集。 提高程式可移植性的一個方法:一般在來源程式中不直接指明使用Unicode還是ANSI版本,而是使用宏彙編中的條件彙編功能來統一替換。比如,在標頭檔中做如下定義:if UNICODE       MessageBox equ <MessageBoxW>else       MessageBox equ <MessageBoxA>endif然後在來源程式的頭部指定UNICODE=1或UNICODE=0,重新編譯後就能產生不同的版本。 未完,待續。。。  參考資料:羅雲彬的《Windows環境下32位組合語言程式設計》(第二版)第三章

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.