最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(wǎng) 會(huì)員登陸 & 注冊(cè)

5.1 匯編語(yǔ)言:匯編語(yǔ)言概述

2023-08-22 13:45 作者:bili_42682284418  | 我要投稿

匯編語(yǔ)言是一種面向機(jī)器的低級(jí)語(yǔ)言,用于編寫(xiě)計(jì)算機(jī)程序。匯編語(yǔ)言與計(jì)算機(jī)機(jī)器語(yǔ)言非常接近,匯編語(yǔ)言程序可以使用符號(hào)、助記符等來(lái)代替機(jī)器語(yǔ)言的二進(jìn)制碼,但最終會(huì)被匯編器編譯成計(jì)算機(jī)可執(zhí)行的機(jī)器碼。

相較于高級(jí)語(yǔ)言(如C、Python等),匯編語(yǔ)言學(xué)習(xí)和使用難度相對(duì)較大,需要對(duì)計(jì)算機(jī)內(nèi)部結(jié)構(gòu)、指令集等有深入的了解,以及具有良好的編程習(xí)慣和調(diào)試能力。但對(duì)于需要對(duì)計(jì)算機(jī)底層進(jìn)行操作的任務(wù),匯編語(yǔ)言是極其高效的,因?yàn)槠淇梢詫?shí)現(xiàn)對(duì)計(jì)算機(jī)底層資源的精細(xì)控制,極大地提高了計(jì)算機(jī)運(yùn)行效率。

盡管在當(dāng)今計(jì)算機(jī)界已經(jīng)不再使用匯編語(yǔ)言來(lái)開(kāi)發(fā)程序,但作為一名安全從業(yè)者掌握匯編語(yǔ)言將會(huì)是高手與專(zhuān)家之間最大的差距,匯編語(yǔ)言作為底層語(yǔ)言,具有直接訪問(wèn)計(jì)算機(jī)硬件和系統(tǒng)資源的能力,因此在系統(tǒng)級(jí)漏洞挖掘、內(nèi)核安全、計(jì)算機(jī)反病毒等領(lǐng)域中具有非常重要的作用。

以下是關(guān)于匯編語(yǔ)言的應(yīng)用場(chǎng)景:

  • ??系統(tǒng)級(jí)漏洞挖掘:許多系統(tǒng)級(jí)漏洞,如堆棧溢出、整數(shù)溢出等,都是由于程序員沒(méi)有理解底層操作系統(tǒng)和硬件的工作原理而導(dǎo)致的。因此,理解匯編語(yǔ)言可以幫助安全研究人員更好地了解底層的操作系統(tǒng)和硬件原理,從而更好地挖掘漏洞。

  • ??內(nèi)核安全:匯編語(yǔ)言是編寫(xiě)內(nèi)核模塊或驅(qū)動(dòng)程序所必需的語(yǔ)言,例如,Linux內(nèi)核中的大部分代碼都是使用匯編語(yǔ)言實(shí)現(xiàn)的。因此,對(duì)于理解內(nèi)核原理和進(jìn)行內(nèi)核安全研究來(lái)說(shuō),掌握匯編語(yǔ)言非常重要。

  • ??計(jì)算機(jī)反病毒:許多計(jì)算機(jī)病毒和惡意軟件都使用匯編語(yǔ)言編寫(xiě),因此掌握匯編語(yǔ)言可以幫助研究人員更好地理解這些惡意軟件的工作原理和行為,并提高反病毒軟件的捕獲率和準(zhǔn)確性。

總之,熟練掌握匯編語(yǔ)言對(duì)于進(jìn)行系統(tǒng)級(jí)漏洞挖掘、內(nèi)核安全研究、計(jì)算機(jī)反病毒等領(lǐng)域都非常有幫助。雖然匯編語(yǔ)言相對(duì)來(lái)說(shuō)比較底層和難以理解,但是深入掌握匯編語(yǔ)言將會(huì)極大地提高軟件安全研究人員的技能和水平,讓讀者從一個(gè)高手蛻變成一名安全專(zhuān)家。

本章中所提到的匯編語(yǔ)言為Windows匯編,在Windows平臺(tái)下讀者可使用MASM工具對(duì)匯編語(yǔ)言進(jìn)行編譯測(cè)試,也可以使用通用的集成開(kāi)發(fā)環(huán)境實(shí)現(xiàn)編譯,筆者推薦使用RadASM工具,RadASM 是一個(gè)面向匯編編程的開(kāi)發(fā)環(huán)境,提供了一系列工具和功能,用于編寫(xiě)、調(diào)試和優(yōu)化匯編語(yǔ)言程序。該工具具有良好的可定制性和擴(kuò)展性,且能提供豐富的工具和功能,方便程序員進(jìn)行匯編語(yǔ)言的開(kāi)發(fā)和調(diào)試工作。

1.1 RadASM

當(dāng)讀者準(zhǔn)備好開(kāi)發(fā)環(huán)境后可打開(kāi)RadASM工具,選擇文件新建工程按鈕,并選擇ConsoleApp選項(xiàng)填入自定義工程名稱(chēng)并一直點(diǎn)擊下一步即可,當(dāng)讀者進(jìn)入到主頁(yè)面后會(huì)看到如下圖所示的窗體,其中最右側(cè)則是我們的項(xiàng)目目錄,該目錄下的Resources則是我們需要測(cè)試代碼的地方,讀者可自行點(diǎn)開(kāi)*.asm文件并在此處寫(xiě)代碼,當(dāng)讀者需要編譯代碼可使用快捷鍵Ctrl+Shift+V快速構(gòu)建,也可點(diǎn)擊右上角的編譯構(gòu)建按鈕自行構(gòu)建;

使用Win32匯編語(yǔ)言做開(kāi)發(fā)其開(kāi)發(fā)感覺(jué)與高級(jí)語(yǔ)言基本一致,并沒(méi)有像大家想象中的那么困難,唯一的區(qū)別只是在高級(jí)語(yǔ)言中可以很容易實(shí)現(xiàn)的語(yǔ)句,而到了匯編語(yǔ)言這里將會(huì)變得較為繁瑣,讀者只要認(rèn)真理解匯編語(yǔ)言中的每一條指令所代表的含義,則同樣可以靈活的運(yùn)用匯編語(yǔ)言開(kāi)發(fā)大型項(xiàng)目,首先筆者來(lái)解釋一下關(guān)于上述圖片中代碼的具體含義;

根據(jù)上述代碼中第一行的定義.386p代表了指令集的選擇,此處代表我們選用Intel 80386處理器的指令集,其中的p則代表將代碼對(duì)齊到32位指令上,接著看第二行.model flat, stdcall此處代表了調(diào)用約定采用stdcall模式,并設(shè)置代碼和數(shù)據(jù)段都使用平坦模型(flat model)來(lái)處理內(nèi)存,第三行option casemap:none代表后續(xù)程序不區(qū)分大小寫(xiě),當(dāng)有了上述這三行定義后匯編語(yǔ)言的預(yù)定義部分也就結(jié)束了。

接著就是比較熟悉的定義語(yǔ)法了,這里的include/includelib分別代表頭文件以及庫(kù)文件的引用,如果讀者需要調(diào)用Windows系統(tǒng)內(nèi)的函數(shù)定義,則此處的頭文件則是必須要包含windows.inc以及kernel32.inc頭的,此外還需要導(dǎo)入kernel32.lib庫(kù)來(lái)完成頭文件功能的導(dǎo)入;

  • ??.data:定義已初始化變量。該指令定義了一個(gè)16位的可賦值變量Main,并將其初始化為1024。

  • ??.data?:定義未初始化變量。該指令定義了一個(gè)32位的未初始化變量lyshark。

  • ??.const:定義常量。該指令定義了一個(gè)以0h(十六進(jìn)制)為結(jié)尾的字符串常量var1,內(nèi)容為“l(fā)yshark”。

  • ??.code:代碼段開(kāi)始。該指令表示代碼段的開(kāi)始。

接下來(lái)就是main PROC以及main ENDP定義了,此處的定義部分讀者可理解為int main()函數(shù),此處的功能同樣是定義主程序入口和結(jié)束,而當(dāng)我們需要編寫(xiě)應(yīng)用程序時(shí)只需要在上方不同的段內(nèi)填充參數(shù)即可,其開(kāi)發(fā)流程可以與高級(jí)語(yǔ)言一致。

1.2 匯編中的變量

MASM 定義了多種內(nèi)部數(shù)據(jù)類(lèi)型,每種數(shù)據(jù)類(lèi)型都描述了該類(lèi)型的變量和表達(dá)式的取值集合,匯編語(yǔ)言中數(shù)據(jù)類(lèi)型的基本特征是以數(shù)據(jù)位數(shù)為度量單位,8,16,32,48,64,80位,而除此之外其他的特征如(符號(hào),指針,浮點(diǎn)數(shù))主要是為了方便我們記憶變量中存儲(chǔ)的數(shù)據(jù)類(lèi)型,如下表中所定義的部分,則是IEEE委員會(huì)發(fā)布的標(biāo)準(zhǔn)內(nèi)部數(shù)據(jù)類(lèi)型;

數(shù)據(jù)類(lèi)型作用(無(wú)符號(hào))數(shù)據(jù)類(lèi)型作用(有符號(hào))BYTE8位無(wú)符號(hào)整數(shù)SBYTE8位有符號(hào)整數(shù)WORD16位無(wú)符號(hào)整數(shù)SWORD16位有符號(hào)整數(shù)DWORD32位無(wú)符號(hào)整數(shù)SWORD32位有符號(hào)整數(shù)FWORD48位整數(shù)(遠(yuǎn)指針)QWORD64位整數(shù)定義REAL432位(4字節(jié))短實(shí)數(shù)REAL864位(8字節(jié))長(zhǎng)實(shí)數(shù)

數(shù)據(jù)類(lèi)型定義語(yǔ)句為變量在內(nèi)存中保留存儲(chǔ)空間,并且可以選擇為變量指定一個(gè)名字,在匯編語(yǔ)言中所有的數(shù)據(jù)無(wú)非就是BYTE的集合,數(shù)據(jù)的定義語(yǔ)句格式如下;

[變量名]?數(shù)據(jù)定義偽指令?初始值[....]

在數(shù)據(jù)定義語(yǔ)句中使用BYTE(定義字節(jié))SBYTE(定義有符號(hào)字節(jié))偽指令,可以為每一個(gè)或多個(gè)有符號(hào)或無(wú)符號(hào)字節(jié)分配存儲(chǔ)空間,每個(gè)初始值必須是8位整數(shù)表達(dá)式或字符常量,例如下面的定義:

.data
??var1?BYTE?'A'??????;?定義字符常量
??var2?BYTE??????????;?定義未初始化變量
??var3?BYTE?0????????;?最小的無(wú)符號(hào)字節(jié)常量
??var4?BYTE?255??????;?最大的無(wú)符號(hào)字節(jié)常量
??var5?SBYTE?-128????;?最小的有符號(hào)字節(jié)常量
??var6?SBYTE?+127????;?最大的有符號(hào)字節(jié)常量

如果一條數(shù)據(jù)定義語(yǔ)句中有多個(gè)初始值,那么標(biāo)號(hào)僅僅代表第一個(gè)初始值的偏移,如下我們首先定義一個(gè)BYTE數(shù)組,然后通過(guò)反匯編查看地址的偏移變化就能看到效果啦:

.data
??list?BYTE?10,20,30,40,50

00E71000?|?B8?0030E700????????|?mov?eax,main.E73000?????????????????|?E73000=10
00E71005?|?B8?0130E700????????|?mov?eax,main.E73001?????????????????|?E73001=20
00E7100A?|?B8?0230E700????????|?mov?eax,main.E73002?????????????????|?E73002=30
00E7100F?|?B8?0330E700????????|?mov?eax,main.E73003?????????????????|?E73003=40
00E71014?|?B8?0430E700????????|?mov?eax,main.E73004?????????????????|?E73004=50

并非所有的數(shù)據(jù)定義都需要標(biāo)號(hào),如果想繼續(xù)定義以list開(kāi)始的字節(jié)數(shù)組,可以在隨后的行上接著上面的定義:

.data
??list?BYTE?10,20,30,40,50
??list?BYTE?60,70,80,90,100

當(dāng)然除了定義整數(shù)字符以外,還可以定義字符串,要想定義字符串應(yīng)將一組字符用單引號(hào)或雙引號(hào)括起來(lái),最常見(jiàn)的字符串是以空格結(jié)尾0h,在C/C++中定義字符串無(wú)需添加結(jié)尾0h,這是因?yàn)榫幾g器會(huì)在編譯的時(shí)候自動(dòng)的在字符串后面填充了0h,在匯編語(yǔ)言中我們需要手動(dòng)添加字符串結(jié)尾的標(biāo)志,以告訴匯編器字符串的結(jié)束。

.data
??string1?BYTE?"hello?lyshark",0h
??string2?BYTE?"good?night",0h

00F23000??68?65?6C?6C?6F?20?6C?79?73?68?61?72?6B?00?67?6F?hello?lyshark.go?
00F23010??6F?64?20?6E?69?67?68?74?00?00?00?00?00?00?00?00?od?night........?

字符串也可以占用多行,而無(wú)須為每行都提供一個(gè)編號(hào),如下代碼也是合法的:

.data
??string1?BYTE?"welcom?to?the?Demo?program"
??????BYTE?"created?by?lyshark",0dh,0ah,
??????BYTE?"url:lyshark"
??????BYTE?"send?me?a?copy",0dh,0ah,0

十六進(jìn)制0dh,0ah也稱(chēng)為CR/LF(回車(chē)換行符),或者是行結(jié)束的字符,在向標(biāo)準(zhǔn)輸出設(shè)備上寫(xiě)的時(shí)候,回車(chē)換行符可以將光標(biāo)移動(dòng)到下一行的開(kāi)頭位置,從而繼續(xù)填充新的字符串。

有時(shí)我們需要初始化一些空值的內(nèi)存空間,在為內(nèi)存地址分配空間的時(shí)候,DUP偽指令就顯得尤為重要,初始化和未初始化數(shù)據(jù)均可使用DUP指令定義,其定義語(yǔ)法如下:

.data
??string1?BYTE?20?DUP(0)???????;?分配20字節(jié),全部填充0
????BYTE?20?DUP(?)?????????????;?分配20字節(jié),且未初始化
????BYTE?50?DUP("stack")???????;?分配50字節(jié),"stackstack..."

.data
??smallArray?DOWRD?10?DUP(0)?;?分配40字節(jié)
??bigArray?DOWOR?5000?DUP(?)?;?分配20000字節(jié)

除了上面的例子以外,我們也可以直接定義常量,常量是不可以動(dòng)態(tài)修改的數(shù)據(jù)類(lèi)型,一般情況下一旦定義,那么在程序運(yùn)行期間不可以被修改,常量的定義很簡(jiǎn)單,只需要將.data換成.const即可。

.const
??var1?BYTE??"hello?world",0h???;?初始化為BYTE的字符串
??var2?DWORD?10?????????????????;?初始化為10DWORD類(lèi)型
??var3?DWORD?100?dup(1,2)???????;?200個(gè)DWORD的緩沖區(qū)
??var4?BYTE??1024?dup(?)????????;?1024字節(jié)的緩沖區(qū)
??var5?BYTE?"welcome",0dh,0ah,0?;?0dh,0ah為換行符

有時(shí)我們需要計(jì)算一個(gè)指定數(shù)組的所占空間的大小,但手動(dòng)計(jì)算顯得特別麻煩,此時(shí)我們可以使用MASM提供的$符號(hào)來(lái)進(jìn)行數(shù)組大小的計(jì)算過(guò)程,如下定義匯編器會(huì)將其進(jìn)行預(yù)處理后回寫(xiě)到變量中存儲(chǔ)。

.data
??list?BYTE?10,20,30,40,50
??listsize?=?($?-?list)???????;?計(jì)算字節(jié)數(shù)據(jù)大小

.data
??list?WORD?1000h,2000h,3000h,4000h
??listsize?=?($?-?list)?/2????;?計(jì)算字?jǐn)?shù)據(jù)大小

.data
??list?DWORD?100000h,200000h,300000h,400000h
??listsize?=?($?-?list)?/4????;?計(jì)算雙字?jǐn)?shù)據(jù)大小

.data
??MyString?BYTE?"hello?lyshark",0h
??MyString_len?=?($?-?MyString)

1.3 標(biāo)準(zhǔn)輸入與輸出

在匯編語(yǔ)言中,有時(shí)我們需要獲取到數(shù)據(jù)的輸入輸出,由于匯編中并不存在屏幕打印功能,此處如果讀者需要使用此功能,則必須調(diào)用系統(tǒng)所提供的庫(kù)函數(shù)來(lái)實(shí)現(xiàn),一般要想實(shí)現(xiàn)輸入輸出有多種圖形,具體來(lái)說(shuō),StdInStdOut分別代表標(biāo)準(zhǔn)輸入流和標(biāo)準(zhǔn)輸出流;WriteFile函數(shù)用于向文件或其他輸出設(shè)備寫(xiě)入數(shù)據(jù);crt_scanfcrt_printf是格式化輸入/輸出函數(shù),這些庫(kù)函數(shù)的調(diào)用都可以使用invoke這個(gè)偽指令來(lái)實(shí)現(xiàn),invoke是MASM中提供的調(diào)用關(guān)鍵字,使用它可實(shí)現(xiàn)調(diào)用各類(lèi)API函數(shù)的目的。

StdIn/StdOut

如果讀者需要使用該函數(shù)輸出,則需要包含masm32.inc頭文件,該頭文件為匯編語(yǔ)言程序員提供了一組常用的宏和函數(shù),在這個(gè)頭文件中,定義了StdIn、StdOutStdErr三個(gè)宏,它們分別代表標(biāo)準(zhǔn)輸入流、標(biāo)準(zhǔn)輸出流和標(biāo)準(zhǔn)錯(cuò)誤流。

使用masm32.inc中的這些宏,可以方便地將輸入輸出重定向到控制臺(tái)或文件中,而無(wú)需直接調(diào)用Windows API函數(shù)。例如,可以使用StdIn宏從控制臺(tái)讀取用戶輸入,使用StdOut宏向控制臺(tái)輸出字符流。這些宏的使用方式與在C語(yǔ)言中使用 stdin 和 stdout 類(lèi)似。

下面是一些示例代碼,使用masm32.inc頭文件來(lái)實(shí)現(xiàn)標(biāo)準(zhǔn)的輸入輸出:

??.386
??.model?flat,?stdcall
??
??include?masm32.inc
??include?kernel32.inc
??includelib?masm32.lib
??includelib?kernel32.lib

.data
??len?equ?20
??OutText?dw??
??ShowText?db?"請(qǐng)輸入一個(gè)數(shù):?",0

.code
??main?PROC
????invoke?StdOut,?addr?ShowText????;?輸出提示信息
????invoke?StdIn,?addr?OutText,len??;?等待用戶的輸入
????invoke?StdOut,?addr?OutText?????;?輸出剛才輸入的內(nèi)容
????ret
??main?ENDP
END?main

crt_printf/crt_scanf

除了使用MASM定義的宏之外,讀者也可以使用C語(yǔ)言庫(kù)函數(shù)中的一些輸出函數(shù),為了使用crt_printf,需要在程序中包含msvcrt.inc頭文件,并將msvcrt.lib庫(kù)作為鏈接器參數(shù)之一。然后,可以使用crt_printf宏來(lái)輸出格式化的文本信息到控制臺(tái)或文件中。

下面是一個(gè)簡(jiǎn)單的使用crt_printf的示例程序:

??.386
??.model?flat,?stdcall
??
??include?msvcrt.inc
??includelib?msvcrt.lib
??
.data
??PrintText?db?"EAX=%d;EBX=%d;EDX=%d?|?InPut?->:?",0
??ScanFomat?db?"%s",0
??PrintTemp?db??
.code
??main?PROC
????mov?eax,10
????mov?ebx,20
????mov?ecx,30
????invoke?crt_printf,addr?PrintText,eax,ebx,ecx????????;?打印提示內(nèi)容
????invoke?crt_scanf,?addr?ScanFomat,?addr?PrintTemp????;?輸入內(nèi)容并接收參數(shù)
????invoke?crt_printf,?addr?PrintTemp???????????????????;?輸出輸入的內(nèi)容
????ret
??main?ENDP
END?main

本文作者: 王瑞 本文鏈接: https://www.lyshark.com/post/9d939a6f.html 版權(quán)聲明: 本博客所有文章除特別聲明外,均采用 BY-NC-SA 許可協(xié)議。轉(zhuǎn)載請(qǐng)注明出處!


5.1 匯編語(yǔ)言:匯編語(yǔ)言概述的評(píng)論 (共 條)

分享到微博請(qǐng)遵守國(guó)家法律
鹤庆县| 山阴县| 安溪县| 弋阳县| 石渠县| 安新县| 积石山| 徐汇区| 襄汾县| 西藏| 庆安县| 永济市| 如东县| 峡江县| 海门市| 东丰县| 凉城县| 庄浪县| 梧州市| 绍兴县| 怀化市| 龙游县| 连城县| 漠河县| 睢宁县| 衡阳市| 鸡东县| 区。| 赞皇县| 台北县| 新竹市| 龙陵县| 周至县| 大洼县| 徐汇区| 清丰县| 黔西县| 乌拉特前旗| 桂平市| 都江堰市| 紫阳县|