匯編基礎(chǔ)(一)

一.認(rèn)識(shí)匯編語言

要認(rèn)識(shí)匯編語言唆铐,還得從編程語言的發(fā)展說起蹲嚣,語言有以下幾種分類采郎,其發(fā)展都是為了讓我們更容易去操縱計(jì)算機(jī):

  • 機(jī)器語言:由0和1組成苔悦。
  • 匯編語言:用符號(hào)代替了0和1净嘀,比機(jī)器語言更便于閱讀和記憶报咳。
  • 高級(jí)語言:Objective-C/Java/C++等,更接近人類語言挖藏,方便程序員的使用暑刃。

舉個(gè)例子??:
以賦值a=b為例(計(jì)算上的操作就是將寄存器BX的內(nèi)容送入寄存器AX):

可以看到我們寫的代碼經(jīng)過編譯轉(zhuǎn)換成計(jì)算機(jī)能夠知道的指令,從而讓計(jì)算機(jī)進(jìn)行相應(yīng)的操作膜眠。匯編語言與機(jī)器語言一一對(duì)應(yīng)岩臣,每一條機(jī)器指令都有與之對(duì)應(yīng)的匯編指令。匯編語言可以通過編譯得到機(jī)器語言宵膨,機(jī)器語言可以通過反匯編得到匯編語言架谎。高級(jí)語言可以通過編譯得到匯編語言\機(jī)器語言,但匯編語言\機(jī)器語言幾乎不可能還原成高級(jí)語言辟躏。

匯編語言有如下特點(diǎn):
① 可以直接訪問谷扣、控制各種硬件設(shè)備,比如存儲(chǔ)器捎琐、CPU等会涎,能最大限度地發(fā)揮硬件的功能涯曲。但是知識(shí)點(diǎn)過多,開發(fā)者需要對(duì)CPU等硬件結(jié)構(gòu)有所了解在塔,所以不易于編寫幻件、調(diào)試、維護(hù)蛔溃。
② 能夠不受編譯器的限制绰沥,對(duì)生成的二進(jìn)制代碼進(jìn)行完全的控制。
③ 目標(biāo)代碼簡(jiǎn)短贺待,占用內(nèi)存少徽曲,執(zhí)行速度快◆锶可能寫的源文件比較大(相對(duì)高級(jí)語言比較啰嗦)秃臣,但是編譯后的目標(biāo)文件、可執(zhí)行文件都小得多哪工。

以c = a + b為例:(對(duì)比匯編語言和C++語言)

④ 匯編指令是機(jī)器指令的助記符,同機(jī)器指令一一對(duì)應(yīng)奥此。每一種CPU都有自己的機(jī)器指令集\匯編指令集,所以匯編語言不具備可移植性雁比。

也是因?yàn)閰R編語言的這些特點(diǎn)稚虎,讓學(xué)習(xí)它有了重要的用途:

  • 理解代碼的本質(zhì),為編寫高效代碼打下基礎(chǔ)偎捎。
  • 理解整個(gè)計(jì)算機(jī)系統(tǒng)的最佳起點(diǎn)和最有效途徑蠢终。
  • 編寫驅(qū)動(dòng)程序、操作系統(tǒng)茴她,對(duì)性能要求極高的程序或者代碼片段寻拂,可與高級(jí)語言混合使用(內(nèi)聯(lián)匯編)
  • 軟件安全、病毒分析與防治

iPhone里面用到的是ARM匯編:

  • armv6:iPhone, iPhone2, iPhone3G, 第一代丈牢、第二代 iPod Touch
  • armv7:3GS,4, 4S,iPad, iPad2, iPad3, iPad mini, iPod Touch 3G, iPod Touch4
  • armv7s:5, 5C, iPad4
  • arm64:5S 及以后 iPhoneX , iPad Air, iPad mini2以后

二. 計(jì)算機(jī)硬件結(jié)構(gòu)基礎(chǔ)與匯編

要想學(xué)好匯編語言祭钉,首先要對(duì)CPU等硬件結(jié)構(gòu)有一定的了解。最為關(guān)鍵的是需要了解CPU和內(nèi)存赡麦,我們遇到的絕大部分指令都是跟內(nèi)存朴皆、CPU有關(guān)的帕识。

App的啟動(dòng)過程如下:

接下來我們具體講講數(shù)據(jù)(指定)的交互泛粹,其中有這么幾個(gè)重要的部件需要了解:
① 總線
② 內(nèi)存
③ 寄存器

① 總線

每一個(gè)CPU芯片都有許多管腳,這些管腳和總線相連肮疗,CPU通過總線跟外部器件進(jìn)行交互晶姊。
總線有三種類型:地址總線、數(shù)據(jù)總線和控制總線伪货。

以CPU從內(nèi)存的3號(hào)單元讀取數(shù)據(jù)為例:

地址總線負(fù)責(zé)傳地址(尋址)们衙,它的寬度決定了CPU的尋址能力钾怔。比如8086的地址總線是20(20根線),尋址能力是1M(2的20次方)(2的10次方就進(jìn)1個(gè)單位蒙挑,B → KB → M)宗侦。
數(shù)據(jù)總線負(fù)責(zé)傳數(shù)據(jù),它的寬度決定了CPU的單次數(shù)據(jù)傳輸量忆蚀,也就是數(shù)據(jù)傳輸速度矾利。比如從內(nèi)存中讀取1024字節(jié)的數(shù)據(jù)(1024B),8086(16位馋袜,即每次傳2字節(jié))至少要讀(傳輸)512次男旗,80386(32位,即每次傳4字節(jié))至少要讀256次欣鳖。 → 我們常說的32位和64位CPU指的就是這個(gè)
控制總線負(fù)責(zé)傳控制命令察皇,它的寬度決定了CPU對(duì)其他器件的控制類型的多少。

例子??:8088的數(shù)據(jù)總線寬度是8(8條線泽台,一條只能傳0和1兩種訊號(hào)什荣,),8086的數(shù)據(jù)總線寬度是16怀酷,分別向內(nèi)存中寫入89D8H(這邊4個(gè)16進(jìn)制溃睹,需要16位,所以8080只能先傳一半)

常見的數(shù)據(jù)寬度:
位(Bit): 1個(gè)位就是1個(gè)二進(jìn)制位0或1胰坟。
字節(jié)(Byte): 1個(gè)字節(jié)由8個(gè)Bit組成(8位)因篇。內(nèi)存中的最小單元Byte。
字(Word): 1個(gè)字由2個(gè)字節(jié)組成(16位)笔横,這2個(gè)字節(jié)分別稱為高字節(jié)和低字節(jié)竞滓。
進(jìn)制占字節(jié)數(shù)
2進(jìn)制:一個(gè)2進(jìn)制占1位,1/8個(gè)字節(jié)吹缔。
8進(jìn)制:一個(gè)8進(jìn)制占3位商佑,3/8個(gè)字節(jié)。
16進(jìn)制:一個(gè)16進(jìn)制占4位厢塘,1/2個(gè)字節(jié)茶没。

8088和8086傳輸數(shù)據(jù).png
② 內(nèi)存

內(nèi)存(Memory)也被稱為內(nèi)存儲(chǔ)器,其作用是用于暫時(shí)存放CPU中的運(yùn)算數(shù)據(jù)晚碾,以及與硬盤等外部存儲(chǔ)器交換的數(shù)據(jù)抓半。只要計(jì)算機(jī)在運(yùn)行中,CPU就會(huì)把需要運(yùn)算的數(shù)據(jù)調(diào)到內(nèi)存中進(jìn)行運(yùn)算格嘁,當(dāng)運(yùn)算完成后CPU再將結(jié)果傳送出來笛求,內(nèi)存的運(yùn)行也決定了計(jì)算機(jī)的穩(wěn)定運(yùn)行。

計(jì)算機(jī)中有各類存儲(chǔ)器,它們的邏輯連接情況如下:


內(nèi)存地址范圍(空間大刑饺搿)受CPU地址總線寬度的限制狡孔。比如8086地址總線寬度是20,可以定位2的20次方不同的內(nèi)存單元蜂嗽,所以內(nèi)存地址范圍為0x00000~0xFFFFF(1個(gè)16位占4),內(nèi)存空間大小為1M苗膝。

各類存儲(chǔ)器地址肯定是不一樣的,他們又不一定是在一塊植旧,所以我們把它想象成一塊虛擬的邏輯存儲(chǔ)器荚醒。如下圖:


每段內(nèi)存地址都有特定的用途:


CPU訪問內(nèi)存單元時(shí),要給出內(nèi)存單元的地址隆嗅。8086有20位地址總線界阁,可以傳送20位的地址,1M的尋址能力(從首地址到尾地址為1M)胖喳。但它又是16位結(jié)構(gòu)的CPU泡躯,它內(nèi)部能夠一次性處理、傳輸丽焊、暫時(shí)存儲(chǔ)的地址為16位较剃。如果將地址從內(nèi)部簡(jiǎn)單地發(fā)出,那么它只能送出16位的地址技健,表現(xiàn)出來的尋址能力只有64KB写穴。
所以,8086采用一種在內(nèi)部用2個(gè)16位地址(段地址和偏移地址)合成的方法來生成1個(gè)20位的物理地址雌贱。8086是用“起始地址(段地址×16(16位就是進(jìn)一格啊送,后面補(bǔ)0)) + 偏移地址 = 物理地址”的方式給出物理地址。

8086的尋址方式.png

為了開發(fā)方便欣孤,我們可以采取分段的方法來管理內(nèi)存馋没,比如:
地址10000H - 100FFH的內(nèi)存單元組成一個(gè)段,該段的起始地址為10000H降传,段地址為1000H篷朵,大小為100H。地址10000H - 1007FH婆排、10080H - 100FFH的內(nèi)存單元組成2個(gè)段声旺,它們的起始地址為:10000H和10080H,段地址為1000H和1008H段只,大小都為80H腮猖。
偏移地址為16位,變化范圍0-FFFFH翼悴,僅用偏移地址來尋址最多可尋64KB個(gè)內(nèi)存單元(尋址能力為64KB缚够,所以一個(gè)段的長(zhǎng)度最大為64KB)。比如給定段地址1000H鹦赎,用偏移地址尋址谍椅,CPU的尋址范圍為:10000H - 1FFFFH。

③ 寄存器

總線和內(nèi)存算是CPU外面的東西古话,接下來我們要說最重要的部分——CPU雏吭。
CPU主要是解釋計(jì)算機(jī)指令以及處理計(jì)算機(jī)軟件中的數(shù)據(jù)。它主要由三大部件構(gòu)成(其內(nèi)部部件之間由總線相連):


CPU組成.png

對(duì)程序員來說陪踩,CPU中最主要部件是寄存器杖们,可以通過改變寄存器的內(nèi)容來實(shí)現(xiàn)對(duì)CPU的控制。
不同的CPU肩狂,寄存器的個(gè)數(shù)摘完、結(jié)構(gòu)是不相同的。比如:8086是16位結(jié)構(gòu)的CPU傻谁,有14個(gè)16位的寄存器(每個(gè)寄存器可以存放2個(gè)字節(jié))孝治。


8086CPU內(nèi)部的寄存器.png

以通用寄存器為例
AX、BX审磁、CX谈飒、DX這4個(gè)寄存器通常用來存放一般性的數(shù)據(jù),稱為通用寄存器(有時(shí)也有特定用途)态蒂。通常杭措,CPU會(huì)先將內(nèi)存中的數(shù)據(jù)存儲(chǔ)到通用寄存器中,然后再對(duì)通用寄存器中的數(shù)據(jù)進(jìn)行運(yùn)算钾恢。

假設(shè)內(nèi)存中有塊紅色內(nèi)存空間的值是3手素,現(xiàn)在想把它的值加1,并將結(jié)果存儲(chǔ)到藍(lán)色內(nèi)存空間瘩蚪。會(huì)有三個(gè)步驟:
① CPU首先會(huì)將紅色內(nèi)存空間的值放到AX寄存器中:mov ax,紅色內(nèi)存空間
② 然后讓AX寄存器與1相加:add ax,1
③ 最后將值賦值給內(nèi)存空間:mov 藍(lán)色內(nèi)存空間,ax

像AX刑桑、BX、CX募舟、DX這4個(gè)寄存器都是16位的祠斧,意味著它們能存16個(gè)0或1,可以存兩個(gè)字節(jié)(byte)拱礁,一個(gè)字(word)琢锋。上一代8086的寄存器都是8位的,為了保證兼容呢灶, AX吴超、BX、CX鸯乃、DX都可分為2個(gè)獨(dú)立的8位寄存器來使用鲸阻。

在匯編的數(shù)據(jù)存儲(chǔ)中跋涣,有2個(gè)比較常用的單位:
字節(jié)(byte):1個(gè)字節(jié)由8bit組成,可以存儲(chǔ)在8位寄存器中鸟悴。
字(word):1個(gè)字由2個(gè)字節(jié)組成陈辱,這2個(gè)字節(jié)分別稱為字的高字節(jié)和低字節(jié)。
比如上圖中细诸,數(shù)據(jù)20000(4E20H沛贪,0100111000100000B),高字節(jié)的值是78震贵,低字節(jié)的值是32利赋。1個(gè)字可以存在1個(gè)16位寄存器中,這個(gè)字的高字節(jié)猩系、低字節(jié)分別存儲(chǔ)在這個(gè)寄存器的高8位寄存器(AH)媚送、低8位寄存器(AL)中。

已知寇甸,8086在訪問內(nèi)存時(shí)要由相關(guān)部件提供內(nèi)存單元的段地址和偏移地址季希,送入地址加法器合成物理地址。那是什么部件提供段地址幽纷?

段地址在8086的段寄存器中存放式塌,8086有4個(gè)段寄存器:CS、DS友浸、SS峰尝、ES,當(dāng)CPU需要訪問內(nèi)存時(shí)由這4個(gè)段寄存器提供內(nèi)存單元的段地址收恢。
CS (Code Segment):代碼段寄存器
DS (Data Segment):數(shù)據(jù)段寄存器
SS (Stack Segment):堆棧段寄存器
ES (Extra Segment):附加段寄存器

CS(代碼段寄存器)

CS為代碼段寄存器武学,IP為指令指針寄存器,它們指示了CPU當(dāng)前要讀取指令的地址伦意。任意時(shí)刻火窒,8086CPU都會(huì)將CS:IP指向的指令作為下一條需要取出執(zhí)行的指令。

CS寄存器.png

步驟如下:
① CS驮肉、IP中的內(nèi)容送入地址加法器熏矿,生成物理地址20000H。
② 地址加法器將物理地址送入輸入輸出控制電路离钝。
③ 輸入輸出控制電路將物理地址20000H送上地址總線票编。
④ 從內(nèi)存20000H單元開始存放的機(jī)器指令(B8 23 01)通過數(shù)據(jù)總線被送入CPU。(為什么是3個(gè)呢卵渴?應(yīng)該是這三個(gè)組成一個(gè)完整的機(jī)器指令慧域,有的是兩個(gè)組成的)
⑤ 輸入輸出控制電路將指令(B8 23 01)送入指令緩沖器。
讀取一條指令后浪读,IP中的值自動(dòng)增加昔榴,以使CPU可以讀取下一條指令辛藻。因當(dāng)前讀入的指令(B8 23 01)為三個(gè)字節(jié),所以IP中的值加3互订。此時(shí)吱肌,CS:IP 指向內(nèi)存單元2000:0003。
⑥ 執(zhí)行控制器執(zhí)行指令(B8 23 01)屁奏,即mov ax 0123H岩榆。
⑦ 指令被執(zhí)行后AX中的內(nèi)容為0123H错负。
此時(shí)坟瓢,CPU將從內(nèi)存單元2000:0003處讀取指令。
⑧ CPU從內(nèi)存20003H處讀取指令(BB 03 30)入指令緩存器犹撒,IP中的值加3折联。
后面指令以此類推。识颊。诚镰。

在8086CPU啟動(dòng)或復(fù)位后,CS:IP 被設(shè)置為FFFFH:0000H祥款,所以FFFF0H單元中的指令是開機(jī)后的第一條指令清笨。

CPU從何處執(zhí)行指令是由CS骏掀、IP中的內(nèi)容決定的队伟,我們可以通過改變CS、IP的內(nèi)容來控制CPU執(zhí)行目標(biāo)指令诊县。

jmp指令(跳轉(zhuǎn))

8086提供了一個(gè)mov指令(傳送指令)桨昙,可以用來修改大部分寄存器的值检号,比如mov ax,10、mov bx,20蛙酪、mov cx,30齐苛、mov dx,40。但是桂塞,mov指令不能用于設(shè)置CS凹蜂、IP的值,8086沒有提供這樣的功能阁危。
8086提供了另外的指令來修改CS炊甲、IP的值,這些指令統(tǒng)稱為轉(zhuǎn)移指令欲芹,最簡(jiǎn)單的是jmp指令卿啡。

jmp 段地址:偏移地址 ?? 用指令中給出的段地址修改CS,偏移地址修改IP
jmp 直接值??用直接值修改IP
jmp 某一合法寄存器??用寄存器中的值修改IP

例子??:
jmp 2AE3:3菱父,執(zhí)行后CS = 2AE3H颈娜,IP = 0003H剑逃,CPU將從2AE33H處讀取指令。

DS(地址段寄存器)

CPU要讀寫一個(gè)內(nèi)存單元時(shí)官辽,必須要先給出這個(gè)內(nèi)存單元的地址蛹磺,在8086中,內(nèi)存地址由段地址和偏移地址組成同仆,8086中有一個(gè)DS段寄存器萤捆,通常用來存放要訪問數(shù)據(jù)的段地址。
舉個(gè)例子??:

mov bx俗批,1000H
mov dx俗或,bx
mov al,[0]

上面3條指令的作用將10000H(1000:0)中的內(nèi)存數(shù)據(jù)賦值到al寄存器中岁忘。mov al,[address]的意思將DS:address中的內(nèi)存數(shù)據(jù)賦值到al寄存器中辛慰,由于al是8位寄存器,所以是將一個(gè)字節(jié)的數(shù)據(jù)賦值給al寄存器(由于8086不支持將數(shù)據(jù)直接送入段寄存器中干像,mov ds,1000H是錯(cuò)誤的)帅腌。

上面的例子中是賦值給al(8位),如果是賦值給ax呢(16位)麻汰?那就是字型數(shù)據(jù)的傳遞(2個(gè)字節(jié)速客,16位)。
在內(nèi)存中五鲫,一個(gè)地址放一個(gè)字節(jié)的數(shù)據(jù)(8位溺职,兩個(gè)16進(jìn)制,如34)臣镣,傳遞字型意味著要2個(gè)內(nèi)存單元辅愿。那是從低內(nèi)存開始或者從高內(nèi)存開始,這就涉及到大小端的概念忆某。

  • 大端模式点待,是指數(shù)據(jù)的高字節(jié)保存在內(nèi)存的低地址中,而數(shù)據(jù)的低字節(jié)保存在內(nèi)存的高地址中(高低\低高)
  • 小端模式弃舒,是指數(shù)據(jù)的高字節(jié)保存在內(nèi)存的高地址中癞埠,而數(shù)據(jù)的低字節(jié)保存在內(nèi)存的低地址中(高高\(yùn)低低)

比如我們常見的x86就是小端模式,ARM小端大端都可以聋呢。

大小端.png

舉個(gè)例子??:

mov指令(賦值)

mov 寄存器苗踪,數(shù)據(jù) // 比如mov ax,8
mov 寄存器削锰,寄存器 // 比如mov ax通铲,bx
mov 寄存器,內(nèi)存單元 // 比如mov ax器贩,[0]
mov 內(nèi)存單元颅夺,寄存器 // 比如mov [0]朋截,ax
mov 段寄存器,寄存器 // 比如mov ds吧黄,ax
mov 寄存器部服,段寄存器 // 比如mov ax,ds
mov 內(nèi)存單元拗慨,內(nèi)存單元 //這個(gè)是錯(cuò)誤的

add和sub指令

add 寄存器廓八,數(shù)據(jù) // 比如add ax,8
add 寄存器赵抢,寄存器 // 比如add ax剧蹂,bx
add 寄存器,內(nèi)存單元 // 比如add ax昌讲,[0]
add 內(nèi)存單元国夜,寄存器 // 比如add [0]减噪,ax

sub 寄存器短绸,數(shù)據(jù) // 比如sub ax,8
sub 寄存器筹裕,寄存器 // 比如sub ax醋闭,bx
sub 寄存器,內(nèi)存單元 // 比如sub ax朝卒,[0]
sub 內(nèi)存單元证逻,寄存器 // 比如sub [0],ax

棧(棧段)

棧:是一種具有特殊的訪問方式的存儲(chǔ)空間(后進(jìn)先出)
8086會(huì)將CS作為代碼段的段地址抗斤,將CS:IP指向的指令作為下一條需要取出執(zhí)行的指令囚企。
8086會(huì)將DS作為數(shù)據(jù)段的段地址,mov ax,[address]就是取出DS:address的內(nèi)存數(shù)據(jù)放到ax寄存器中瑞眼。
8086會(huì)將SS作為棧段的段地址龙宏,任意時(shí)刻,SS:SP指向棧頂元素伤疙。
8086提供了PUSH(入棧)和POP (出棧)指令來操作棧段的數(shù)據(jù)
比如push ax是將ax的數(shù)據(jù)入棧银酗,pop ax是將棧頂?shù)臄?shù)據(jù)送入ax。
椡较瘢空時(shí)黍特,SS:SP指向棧空間最高地址單元的下一個(gè)單元(就是棧的下面锯蛀,棧外了)灭衷。

push.png
pop.png

push和pop指令
在8086中,push旁涤、pop操作的數(shù)據(jù)都是2個(gè)字節(jié)的翔曲,也就是以字為單位的经备。

push 寄存器 // 將一個(gè)寄存器中的數(shù)據(jù)入棧
pop 寄存器 //用一個(gè)寄存器接收出棧的數(shù)據(jù)
push 段寄存器 // 將一個(gè)段寄存器中的數(shù)據(jù)入棧
pop 段寄存器 //用一個(gè)段寄存器接收出棧的數(shù)據(jù)
push 內(nèi)存單元 // 將一個(gè)內(nèi)存單元處的字(也就是開始的兩個(gè)內(nèi)存單元)入棧
pop 內(nèi)存單元 //用一個(gè)內(nèi)存單元接收出棧的數(shù)據(jù)

舉個(gè)例子??:

mov ax,1000H
mov dx部默,ax //dx = 1000H
push [0] //將1000:0處的字壓入棧中
pop [2] //出棧的數(shù)據(jù)送入1000:2處

段的總結(jié)

我們可以用一個(gè)段存放數(shù)據(jù)侵蒙,將它定義為“數(shù)據(jù)段”
我們可以用一個(gè)段存放代碼傅蹂,將它定義為“代碼段”纷闺;
我們可以用一個(gè)段當(dāng)作棧,將它定義為“棧段”份蝴。

對(duì)于數(shù)據(jù)段犁功,將它的段地址放在DS中,用mov婚夫、add浸卦、sub等訪問內(nèi)存單元的指令時(shí),CPU就將我們定義的數(shù)據(jù)段中的內(nèi)容當(dāng)做數(shù)據(jù)來訪問案糙;
對(duì)于代碼端限嫌,將它的段地址放在CS中,將段中第一條指令的偏移地址放在IP中时捌,這樣CPU就將執(zhí)行我們定義的代碼段中的指令怒医;
對(duì)于棧段,將它的段地址放在SS中奢讨,將棧頂單元的偏移地址放在SP中稚叹,這樣CPU在需要進(jìn)行棧操作的時(shí)候,比如執(zhí)行push拿诸、pop指令等扒袖,就將我們定義的棧段當(dāng)成棧空間來用亩码。

三.完整的匯編程序

完整的匯編程序包含匯編指令和偽指令季率。
匯編指令如mov、add蟀伸、sub等蚀同,有對(duì)應(yīng)的機(jī)器指令,可以被編譯為機(jī)器指令啊掏,最終被CPU執(zhí)行蠢络。偽指令如assume、 segment迟蜜、ends刹孔、end等,沒有對(duì)應(yīng)的機(jī)器指令,由編譯器解析髓霞,最終不被CPU執(zhí)行卦睹。

// 聲明一下code段是cs段、代碼段
assume cs:code
// segment和ends的作用是定義一個(gè)段,code是我們?nèi)〉亩蚊?code segment
    mov ax, 1122h
    mov bx, 3344h
    add ax, bx     
    
    // 正常退出程序
    mov ax, 4c00h
    int 21h    
code ends 

// 編譯器遇到end時(shí)方库,就結(jié)束對(duì)源程序的編譯
end 

使用匯編語言編寫一個(gè)完整的程序结序,步驟大致如下:
編寫源代碼 → 編譯、鏈接 → 調(diào)試纵潦、運(yùn)行

源程序->可執(zhí)行文件.png

在完整的匯編程序中徐鹤,我們會(huì)看到常見的幾種語法。

  • 中斷int
  • 循環(huán)loop
  • call和ret指令

中斷int
可以通過指令int n產(chǎn)生中斷邀层,n是中斷碼返敬,內(nèi)存中有一張中斷向量表,用來存放中斷碼對(duì)應(yīng)中斷處理程序的入口地址寥院。
CPU在接收到中斷信號(hào)后劲赠,暫停當(dāng)前正在執(zhí)行的程序,跳轉(zhuǎn)到中斷碼對(duì)應(yīng)的中斷向量表地址處秸谢,去執(zhí)行中斷處理程序凛澎。

常見中斷:

  • int 10h用于執(zhí)行BIOS中斷
  • int 3是“斷點(diǎn)中斷”,用于調(diào)試程序
  • int 21h用于執(zhí)行DOS系統(tǒng)功能調(diào)用钮追,AH寄存器存儲(chǔ)功能號(hào)

循環(huán)loop
loop指令和cx配合使用预厌,用于循環(huán)執(zhí)行重復(fù)的操作阿迈,類似于高級(jí)語言中的for元媚、while循環(huán)。
loop指令的執(zhí)行流程苗沧,讓cx的值減一刊棕,判斷cx的值。

       mov ax, 2h
       mov cx, 5    // 5為循環(huán)次數(shù)
s:     add ax, ax   // s為標(biāo)號(hào)
       loop  s      // 循環(huán)執(zhí)行標(biāo)號(hào)的程序待逞,即 add ax, ax 

call和ret指令
call是將下一條指令的偏移地址入棧后甥角,轉(zhuǎn)到標(biāo)號(hào)處執(zhí)行指令。

call 標(biāo)號(hào)

ret是將棧頂?shù)闹党鰲J队#x值給ip嗤无。

四.棧幀

棧幀就是一個(gè)函數(shù)執(zhí)行的環(huán)境,包括:參數(shù)怜庸、局部變量当犯、返回地址等。
每個(gè)函數(shù)都有自己對(duì)應(yīng)的棧幀割疾,用來保存(或者說保護(hù))自己的數(shù)據(jù)嚎卫。

棧幀的介紹.png
棧幀的詳情1.png
棧幀的詳情2.png

以下是關(guān)于函數(shù)執(zhí)行過程,棧幀的變化(對(duì)應(yīng)的圖片如下):

  1. push 參數(shù)
  2. push 函數(shù)的返回地址
  3. push bp (保留bp之前的值宏榕,方便以后恢復(fù))
  4. mov bp, sp (保留sp之前的值拓诸,方便以后恢復(fù))
  5. sub sp,空間大小 (分配空間給局部變量)
  6. 保護(hù)可能要用到的寄存器
  7. 使用CC(int 3)填充局部變量的空間
  8. --------執(zhí)行業(yè)務(wù)邏輯--------
  9. 恢復(fù)寄存器之前的值
  10. mov sp, bp (恢復(fù)sp之前的值)
  11. pop bp (恢復(fù)bp之前的值)
  12. ret (將函數(shù)的返回地址出棧侵佃,執(zhí)行下一條指令)
  13. 恢復(fù)棧平衡 (add sp,參數(shù)所占的空間)
棧幀.jpeg
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市奠支,隨后出現(xiàn)的幾起案子馋辈,更是在濱河造成了極大的恐慌,老刑警劉巖倍谜,帶你破解...
    沈念sama閱讀 206,126評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件首有,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡枢劝,警方通過查閱死者的電腦和手機(jī)井联,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,254評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來您旁,“玉大人烙常,你說我怎么就攤上這事『缀校” “怎么了蚕脏?”我有些...
    開封第一講書人閱讀 152,445評(píng)論 0 341
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)侦锯。 經(jīng)常有香客問我驼鞭,道長(zhǎng),這世上最難降的妖魔是什么尺碰? 我笑而不...
    開封第一講書人閱讀 55,185評(píng)論 1 278
  • 正文 為了忘掉前任挣棕,我火速辦了婚禮,結(jié)果婚禮上亲桥,老公的妹妹穿的比我還像新娘洛心。我一直安慰自己,他們只是感情好题篷,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,178評(píng)論 5 371
  • 文/花漫 我一把揭開白布词身。 她就那樣靜靜地躺著,像睡著了一般番枚。 火紅的嫁衣襯著肌膚如雪法严。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 48,970評(píng)論 1 284
  • 那天葫笼,我揣著相機(jī)與錄音深啤,去河邊找鬼。 笑死渔欢,一個(gè)胖子當(dāng)著我的面吹牛墓塌,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 38,276評(píng)論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼苫幢,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼访诱!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起韩肝,我...
    開封第一講書人閱讀 36,927評(píng)論 0 259
  • 序言:老撾萬榮一對(duì)情侶失蹤触菜,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后哀峻,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體涡相,經(jīng)...
    沈念sama閱讀 43,400評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,883評(píng)論 2 323
  • 正文 我和宋清朗相戀三年剩蟀,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了催蝗。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 37,997評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡育特,死狀恐怖丙号,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情缰冤,我是刑警寧澤犬缨,帶...
    沈念sama閱讀 33,646評(píng)論 4 322
  • 正文 年R本政府宣布,位于F島的核電站棉浸,受9級(jí)特大地震影響怀薛,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜迷郑,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,213評(píng)論 3 307
  • 文/蒙蒙 一枝恋、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧三热,春花似錦鼓择、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,204評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽念搬。三九已至抑堡,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間朗徊,已是汗流浹背首妖。 一陣腳步聲響...
    開封第一講書人閱讀 31,423評(píng)論 1 260
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留爷恳,地道東北人有缆。 一個(gè)月前我還...
    沈念sama閱讀 45,423評(píng)論 2 352
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國和親棚壁。 傳聞我的和親對(duì)象是個(gè)殘疾皇子杯矩,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,722評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容

  • 語言的發(fā)展 機(jī)器語言: 由0和1組成的機(jī)器指令. 如:0101 0001 1101 0110匯編語言(assemb...
    hfzhangzhang閱讀 287評(píng)論 0 0
  • 匯編語言的發(fā)展 機(jī)器語言 由0和1組成的機(jī)器指令. 加:0100 0000 減:0100 1000 乘:1111 ...
    宵衣旰食閱讀 610評(píng)論 1 0
  • 機(jī)器語言:由0和1組成的機(jī)器指令 高級(jí)語言:更接近人類的語言如 oc,swift袖外,c... 一條匯編指令和一條機(jī)器...
    領(lǐng)悟12138閱讀 435評(píng)論 0 0
  • 引言 什么是匯編語言史隆?答:匯編語言是計(jì)算機(jī)語言,通俗來講就是人類與計(jì)算機(jī)(CPU)交流的橋梁曼验,計(jì)算機(jī)不認(rèn)識(shí)人類的語...
    struggle3g閱讀 1,928評(píng)論 1 6
  • 王爽匯編全書知識(shí)點(diǎn)大綱 第一章 基礎(chǔ)知識(shí) 機(jī)器語言 匯編語言的產(chǎn)生 匯編語言的組成 存儲(chǔ)器 cpu對(duì)存儲(chǔ)器的讀寫 ...
    2c3ba901516f閱讀 2,407評(píng)論 0 1