汇编语言整数加减法示例
在《第一個(gè)匯編語言程序》一節(jié)中給出的 AddTwo 程序,并添加必要的聲明使其成為完全能運(yùn)行的程序。
?
; AddTwo.asm -兩個(gè) 32 位整數(shù)相加 .386 .model flat,stdcall .stack 4096 ExitProcess PROTO, dwExitCode:DWORD .code main PROC mov eax,5 ;將數(shù)字5送入eax寄存器 add eax,6 ;eax寄存器加6 INVOKE ExitProcess,0 main ENDP END main第 3 行是 .386 偽指令,它表示這是一個(gè) 32 位程序,能訪問 32 位寄存器和地址。第 4 行選擇了程序的內(nèi)存模式(flat),并確定了子程序的調(diào)用規(guī)范(稱為 stdcall)。其原因是 32 位 Windows 服務(wù)要求使用 stdcall 規(guī)范。第 5 行為運(yùn)行時(shí)堆棧保留了 4096 字節(jié)的存儲空間,每個(gè)程序都必須有。
第 6 行聲明了 ExitProcess 函數(shù)的原型,它是一個(gè)標(biāo)準(zhǔn)的 Windows 服務(wù)。原型包含了函數(shù)名、PROTO 關(guān)鍵字、一個(gè)逗號,以及一個(gè)輸入?yún)?shù)列表。ExitProcess 的輸入?yún)?shù)名稱為 dwExitCode。
可以將其看作為給 Windows 操作系統(tǒng)的返回值,返回值為零,則表示程序執(zhí)行成功;而任何其他的整數(shù)值都表示了一個(gè)錯誤代碼。因此,程序員可以將自己的匯編程序看作是被操作系統(tǒng)調(diào)用的子程序或過程。當(dāng)程序準(zhǔn)備結(jié)束時(shí),它就調(diào)用 ExitProcess,并向操作系統(tǒng)返回一個(gè)整數(shù)以表示該程序運(yùn)行良好。
大家可能會好奇,為什么操作系統(tǒng)想要知道程序是否成功完成。理由如下:與按序執(zhí)行一些程序相比,系統(tǒng)管理員常常會創(chuàng)建腳本文件。在腳本文件中的每一個(gè)點(diǎn)上,系統(tǒng)管理員都需要知道剛執(zhí)行的程序是否失敗,這樣就可以在必要時(shí)退出該腳本。
腳本通常如下例所示,其中,ErrorLevel1 表示前一步的過程返回碼大于或等于 1 :
call program_1 if ErrorLevel 1 goto FailedLabel call program_2 if ErrorLevel 1 goto FailedLabel :SuccessLabel. Echo Great, everything worked!現(xiàn)在回到 AddTwo 程序清單。第 15 行用 end 偽指令來標(biāo)記匯編的最后一行,同時(shí)它也標(biāo)識了程序的入口(main)。標(biāo)號 main 在第 9 行進(jìn)行了聲明,它標(biāo)記了程序開始執(zhí)行的地址。
匯編偽指令回顧
現(xiàn)在回顧一些在示例程序中使用過的最重要的匯編偽指令。
首先是 .MODEL 偽指令,它告訴匯編程序用的是哪一種存儲模式:
.model flat,stdcall32 位程序總是使用平面(flat)存儲模式,它與處理器的保護(hù)模式相關(guān)聯(lián)。關(guān)鍵字 stdcall 在調(diào)用程序時(shí)告訴匯編器,怎樣管理運(yùn)行時(shí)堆棧。然后是 .STACK 偽指令,它告訴匯編器應(yīng)該為程序運(yùn)行時(shí)堆棧保留多少內(nèi)存字節(jié):
.stack 4096數(shù)值 4096 可能比將要用的字節(jié)數(shù)多,但是對處理器的內(nèi)存管理而言,它正好對應(yīng)了一個(gè)內(nèi)存頁的大小。所有的現(xiàn)代程序在調(diào)用子程序時(shí)都會用到堆棧。首先,用來保存?zhèn)鬟f的參數(shù);其次,用來保存調(diào)用函數(shù)的代碼的地址。
函數(shù)調(diào)用結(jié)束后,CPU 利用這個(gè)地址返回到函數(shù)被調(diào)用的程序點(diǎn)。此外,運(yùn)行時(shí)堆棧還可以保存局部變量,也就是,在函數(shù)內(nèi)定義的變量。
.CODE 偽指令標(biāo)記一個(gè)程序代碼區(qū)的起點(diǎn),代碼區(qū)包含了可執(zhí)行指令。通常,.CODE 的下一行聲明程序的入口,按照慣例,一般會是一個(gè)名為 main 的過程。程序的入口是指程序要執(zhí)行的第一條指令的位置。用下面兩行來傳遞這個(gè)信息:
.code main PROCENDP 偽指令標(biāo)記一個(gè)過程的結(jié)束。如果程序有名為 main 的過程,則 endp 就必須使用同樣的名稱:
main ENDP最后,END 偽指令標(biāo)記一個(gè)程序的結(jié)束,并要引用程序入口:
END main如果在 END 偽指令后面還有更多代碼行,它們都會被匯編程序忽略。程序員可以在這里放各種內(nèi)容一一程序注釋,代碼副本等等,都無關(guān)緊要。
運(yùn)行和調(diào)試 AddTwo 程序
使用 Visual Studio 可以很方便地編輯、構(gòu)建和運(yùn)行匯編語言程序。下面的步驟,按照 Visual Studio 2012,說明了怎樣打開示例項(xiàng)目,并創(chuàng)建 AddTwo 程序:
1) 啟動計(jì)算機(jī)上安裝的最新版本的 Visual Studio。
2) 打開 Visual Studio 中 Solution Explorer 窗口。它應(yīng)該已經(jīng)是可見的,但是程序員也可以在 View 菜單中選擇 Solution Explorer 使其可見。
3) 在 Solution Explorer 窗口右鍵點(diǎn)擊項(xiàng)目名稱,在文本菜單中選擇 Add,再在彈出菜單中選擇 New Item。
4) 在 Add New File 對話窗口中(如下圖所示 ) ,將文件命名為 AddTwo.asm,填寫 Location 項(xiàng)為該文件選擇一個(gè)合適的磁盤文件夾。
5) 單擊 Add 按鈕保存文件。
6) 鍵入程序源代碼,如下所示。這里大寫關(guān)鍵字不是必需的:
; AddTwo.asm - adds two 32-bit integers. .386 .model flat,stdcall .stack 4096 ExitProcess PROTO,dwExitCode:DWORD .code main PROC mov eax, 5 add eax, 6 INVOKE ExitProcess,0 main ENDP END main7) 在 Project 菜單中選擇 Build Project,查看 Visual Studio 工作區(qū)底部的錯誤消息。這被稱為錯誤列表窗口。注意,當(dāng)沒有錯誤時(shí),窗口底部的狀態(tài)欄會顯示 Build succeeded。
調(diào)試演示
下面將展示 AddTwo 程序的一個(gè)示例調(diào)試會話。演示使用的是 Visual Studio 2012,不過,自 2008 年起的任何版本的 Visual Studio 都可以使用。
運(yùn)行調(diào)試程序的一個(gè)方法是在 Debug 菜單中選擇 Step Over。按照 Visual Studio 的配置,F10 功能鍵或 Shift+F8 組合鍵將執(zhí)行 Step Over 命令。
開始調(diào)試會話的另一種方法是在程序語句上設(shè)置斷點(diǎn),方法是在代碼窗口左側(cè)灰色垂直條中直接單擊。斷點(diǎn)處由一個(gè)紅色大圓點(diǎn)標(biāo)識出來。然后就可以從 Debug 菜單中選擇 Start Debugging 開始運(yùn)行程序。
如果試圖在非執(zhí)行代碼行設(shè)置斷點(diǎn),那么在運(yùn)行程序時(shí),Visual Studio 會直接將斷點(diǎn)前移到下一條可執(zhí)行代碼行。
當(dāng)調(diào)試器被激活時(shí),Visual Studio 窗口底部的狀態(tài)欄變?yōu)槌壬.?dāng)調(diào)試器停止并返回編輯模式時(shí),狀態(tài)欄變?yōu)樗{(lán)色。可視提示是有用的,因?yàn)樵谡{(diào)試器運(yùn)行時(shí),程序員無法對程序進(jìn)行編輯或保存。
自定義調(diào)試接口
在調(diào)試時(shí)可以自定義調(diào)試接口。例如,如果想要顯示 CPU 寄存器,實(shí)現(xiàn)方法是,在 Debug 菜單中選擇 Windows,然后再選擇 Registerso, 其中 Registers 窗口可見,同時(shí)還關(guān)閉了一些不重要的窗口。EAX 數(shù)值顯示為 0000000B,是十進(jìn)制數(shù) 11 的十六進(jìn)制表示。
Registers 窗口中,EFL 寄存器包含了所有的狀態(tài)標(biāo)志位(零標(biāo)志、進(jìn)位標(biāo)志、溢出標(biāo)志等)。如果在 Registers 窗口中 右鍵單擊,并在彈出菜單中選擇Flags,則窗口將顯示單個(gè)的標(biāo)志位值。
Registers 窗口的一個(gè)重要特點(diǎn)是,在單步執(zhí)行程序時(shí),任何寄存器,只要當(dāng)前指令修改了它的數(shù)值,就會變?yōu)榧t色。盡管無法在打印頁面(它只有黑白兩色)上表示出來,這種紅色高亮確實(shí)顯示給程序員,使之了解其程序是怎樣影響寄存器的。?
在 Visual Studio 中運(yùn)行一個(gè)匯編語言程序時(shí),它是在控制臺窗口中啟動的。這個(gè)窗口與從 Windows 的 Start 菜單運(yùn)行名為 cmd.exe 程序的窗口是相同的。或者,還可以打開項(xiàng)目 DebugBin 文件夾中的命令提示符,直接從命令行運(yùn)行應(yīng)用程序。如果采用的是這個(gè)方法,程序員就只能看見程序的輸出,其中包括了寫入控制臺窗口的文本。查找具有相同名稱的可執(zhí)行文件作為 Visual Studio 項(xiàng)目。
下一篇:匯編器
強(qiáng)力推薦閱讀文章
年薪40+W的大數(shù)據(jù)開發(fā)【教程】,都在這兒!
總結(jié)
以上是生活随笔為你收集整理的汇编语言整数加减法示例的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: php将图片导入,php中图片文件的导入
- 下一篇: Linux服务器安全之用户密钥认证登录(