9 20第一次作業

2021-08-08 13:23:40 字數 4379 閱讀 3723

eax, ebx, ecx, edx, esi, edi, ebp, esp等都是x86 組合語言中cpu上的通用暫存器的名稱,是32位的暫存器。如果用c語言來解釋,可以把這些暫存器當作變數看待。

比方說: add eax,-2 ;   

//可以認為是給變數eax加上-2這樣的乙個值。

這些32位暫存器有多種用途,但每乙個都有「專長」,有各自的特別之處。

eax  是"累加器"(accumulator), 它是很多加法乘法指令的預設暫存器。

ebx  是"基位址"(base)暫存器, 在記憶體定址時存放基位址。

ecx  是計數器(counter), 是重複(rep)字首指令和loop指令的內定計數器。

edx  則總是被用來放整數除法產生的餘數。

esi/edi 分別叫做"源/目標索引暫存器"(source/destination index),因為在很多字串操作指令中, ds:esi指向源串,而es:edi指向目標串.

ebp 是"基址指標"(base pointer), 它最經常被用作高階語言函式呼叫的"框架指標"(frame pointer). 在破解的時候,經常可以看見乙個標準的函式起始**:

push ebp ; 儲存當前ebp

mov ebp,esp ; ebp設為當前堆疊指標

sub esp, *** ; 預留***位元組給函式臨時變數.

...這樣一來,ebp 構成了該函式的乙個框架, 在ebp上方分別是原來的ebp, 返回位址和引數. ebp下方則是臨時變數. 函式返回時作mov esp,ebp/pop ebp/ret  即可.

esp  專門用作堆疊指標,被形象地稱為棧頂指標,堆疊的頂部是位址小的區域,壓入堆疊的資料越多,esp也就越來越小。在32位平台上,esp每次減少4位元組。

1.eip 

2.esp 

3.ebp 

1.eip

暫存器裡儲存的是

cpu下次要執行的指令的位址

。也就是呼叫完

fun函式後,讓

cpu知道應該執行

main

函式中的

printf("

函式呼叫結束")

語句了。

2.ebp

暫存器裡儲存的是是棧的棧底指標,通常叫棧基址

,這個是一開始進行

fun()

函式呼叫之前,由

esp傳遞給

ebp的。

(在函式呼叫前你可以這麼理解:

esp儲存的是棧頂位址,

也是棧底位址。)3.

esp暫存器裡儲存的是在呼叫函式

fun()

之後,棧的棧頂

。並且始終指向棧頂。

堆疊是一種簡單的資料結構,是一種只允許在其一端進行插入或刪除的線性表。

允許插入或刪除操作的一端稱為棧頂,

另一端稱為棧底,

對堆疊的插入和刪除操作被稱入棧和

出棧。有一組cpu

指令可以實現對程序的記憶體實現堆疊訪問。其中,

pop指令實現

出棧操作,

push

指令實現

入棧操作。

cpu的

esp暫存器存放

當前執行緒的棧頂指標

,ebp

暫存器中儲存

當前執行緒的棧底指標

。cpu

的eip

暫存器存放

下乙個cpu

指令存放的記憶體位址,當

cpu執行完當前的指令後,

從eip

esp和

ebp區別

1.eip 

2.esp 

3.ebp 

1.eip暫存器裡儲存的是cpu下次要執行的指令的位址。 

也就是呼叫完fun函式後,讓cpu知道應該執行main函式中的printf("函式呼叫結束")語句了。 

2.ebp暫存器裡儲存的是是棧的棧底指標,通常叫棧基址,這個是一開始進行fun()函式呼叫之前,由esp傳遞給ebp的。(在函式呼叫前你可以這麼理解:esp儲存的是棧頂位址,也是棧底位址。) 

3.esp暫存器裡儲存的是在呼叫函式fun()之後,棧的棧頂。並且始終指向棧頂。 堆疊是一種簡單的資料結構,是一種只允許在其一端進行插入或刪除的線性表。 

允許插入或刪除操作的一端稱為棧頂,另一端稱為棧底,對堆疊的插入和刪除操作被稱入棧和出棧。  

有一組cpu指令可以實現對程序的記憶體實現堆疊訪問。其中,pop指令實現出棧操作,push指令實現入棧操作。  

cpu的esp暫存器存放當前執行緒的棧頂指標,  

ebp暫存器中儲存當前執行緒的棧底指標。  

cpu的eip暫存器存放下乙個cpu指令存放的記憶體位址,當cpu執行完當前的指令後,從eip暫存器中讀取下一條指令的記憶體位址,然後繼續執行。 

lea si,d1

是把d1的位址放入si暫存器中。

所以si中的值會變的,變成的是d1的位址。而d1則是使用者定義的乙個記憶體資料的助記符。

如果是mov si,d1就會把d1的值放進si。

例如,d1 dw 0x0000

彙編以後可能變成:

位址 值

0x9000 00

0x9001 00

那麼lea si,d1,si的值是0x9000而不是0000,要用mov就是0000了

在組合語言中,mov指令是資料傳送指令,也是最基本的程式設計指令,用於將乙個資料從源位址傳送到目標位址(暫存器間的資料傳送本質上也是一樣的)。其特點是不破壞源位址單元的內容。

例如:mov ax,2000h;將16位資料2000h傳送到ax暫存器

mov al,20h;將8位資料20h傳送到al暫存器

mov ax,bx;將bx暫存器的16位資料傳送到ax暫存器

mov al,[2000h];將2000h單元的內容傳送到al暫存器

需要注意的是:

(1)兩個儲存單元之間不能直接傳送資料,即:mov指令只允許乙個運算元在儲存器中。mov [si],[2000h];這是錯誤的

(2)mov指令中立即數不能直接傳送給段暫存器(cs、ds、ss、es)和ip;段暫存器之間不能直接傳送。mov ip,2000 h ;這是錯誤的

(3)cs和ip不能作為目的運算元。mov cs,ax ;這是錯誤的

(4)mov指令中立即數不能作目標運算元。mov 2000h,[si] ;這是錯誤的

在這裡ret指令的內部操作是:棧頂字單元出棧,其值賦給ip暫存器。即實現了乙個程式的轉移,將棧頂字單元儲存的偏移位址作為下一條指令的偏移位址。
pushax是把ax裡的值壓入堆疊。即當前esp-4出的值變為ax的值,ax本身的值不變。

popdx是把當esp指向的棧中的值(即之前push ax進棧的ax的值)賦給dx

並且esp+4(dx的值改變,esp在pop之前指向的地方的值不變,還是之前ax進棧後的值,即堆疊裡的那個值不會自動清零)

可以直接在debug裡實踐,然後看它們的值,就是實際經驗了

不同的cpu可能有不同的規定。下面只說常見的簡單cpu的指令。

常見的cpu的call指令(「呼叫」指令)的功能,就是以下兩點:

(1)將下一條指令的所在位址(即當時程式計數器pc的內容)入棧,

(2)並將子程式的起始位址送入pc(於是cpu的下一條指令就會轉去執行子程式)。

而子程式結尾處通常都要編寫一條ret指令(「返回」指令),ret指令的功能就是一條:

從棧中取出一條資料送入pc。

從上面敘述可以看出,正常情況下,ret指令從棧中取出的一條資料,也就是當初被call指令所入棧的下一條指令的所在位址。

因此,ret指令後,cpu的下一條指令就回去執行當初的call指令的下一條了。

jmp 就是無條件轉移指令啊,遇到jmp 就轉移,

跳轉指令不止jmp,jmp是無條件跳轉,jmp要配合條件跳轉指令使用

比如c語言程式

:s=0;

for (int i=0;i<10;++i)

可能會編譯為等效如下彙編**的指令:

mov eax,0

mov ebx,0

loop1:

cmp ebx,10

jge out

add eax,ebx

add ebx,1

jmp loop1

out:

mov s,eax

這裡jmp就和jge配合使用

sub是減法運算。

比如mov ax,2

mov bx,1

sub ax,bx

其中sub ax,bx就是ax中的值減bx中的值,等於1,然後把結果,也就是1,放入ax中。

add指令,是一種計算機指令,含義為兩數相加(不帶進製)。oprd1為任一通用暫存器或儲存器運算元,可以是任意乙個通用暫存器,而且還可以是任意乙個儲存器運算元。

第一次作業

1.用較低的成本,開發出滿足客戶需求的軟體,開發的軟體可靠性高,易於維護和移植 2.分為設計階段,開發階段和測試執行階段 1 設計階段 分析客戶需求,明確要解決哪些問題,實現哪些功能,以及確定基本方法 2 開發階段 a.概要設計 畫出流程圖,進行模組化劃分,建立模組的層次結構以及呼叫關係 b.詳細設...

第一次作業

1.4 非計算機專業 程式和軟體有何不同?答 程式是通過計算機語言寫出來的具有許多演算法的摸板,是實現軟體功能的底層推手 推手的意思可以理解為動力 所以,程式是軟體的內在因子,而軟體是乙個或多個程式通過編譯器編譯出來的成品。1.3 查詢資料,解釋什麼是圖靈測試?答 指測試者與被測試者 乙個人和一台機...

第一次作業

1.解釋什麼是圖靈測試?圖靈測試 又稱 圖靈判斷 是圖靈提出的乙個關於機械人的著名判斷原則。一種測試機器是不是具備人類智慧型的方法。如果說現在有一台電腦,其運算速度非常快 記億容量和邏揖單元的數目也超過了人腦,而且還為這台電腦編寫了許多智慧型化的程式,並提供了合適種類的大量資料,使這台電腦能夠做一些...