系統中斷流程 尋址方式 寄存器與觸發器的關係 微處理器 用一個或多箇中斷號來對應全部的系統調用

 

https://www.kancloud.cn/wintry/python3/742474python

微機性能指標:linux

1)CPU類型:CPU型號決定了微機系統的檔次 2)字長:CPU一次能夠同時傳送和處理的數碼的位數 直接關係到計算機的計算精度、尋址速度和處理能力 字長越長,表示一次處理範圍越大,性能越好 3)主頻:計算機的時鐘頻率。 CPU單位時間內(秒)發出的脈衝數,吉赫(GHz);主頻越高運算越快 4)內存容量:內存儲器可容納的二進制信息總量。 以字節B(Byte)表示,8位二進制爲1字節,1024B=1KB. 

微型計算機的組成:程序員

微型計算機是由大規模集成電路組成,體積較小的電子計算機。
微機包括硬件系統和軟件系統;
硬件系統是組成微機的各類物理設備包括主機和外設。
主機以微處理器爲基礎,配以存儲器及I/O設備。算法

計算機硬件5個基本組成部分:運算器、控制器、存儲器、輸入設備、輸出設備
微處理器:一片或幾片大規模集成電路組成的,具備運算和控制功能的中央處理單元。主要由算數邏輯部件ALU、寄存器和控制器CU組成。
現代計算機能實現自動化的信息處理,是因爲採用了馮.諾依曼「存儲程序」
工做原理。
主板是計算機各類部件相互鏈接的紐帶和橋樑。
寄存器與觸發器的關係:編程

因爲一個觸發器可以存儲一位二進制碼,因此把n個觸發器的時鐘端口鏈接起來就能構成一個存儲n位二進制碼的寄存器。安全

總線:markdown

bus 是計算機系統各部件之間相互鏈接,傳送信息的公共通道,由一組物理導線組成。
一次傳輸信息的位數稱爲總線的寬度。數據結構

按照傳送信息類型能夠分爲:數據總線,地址總線和控制總線框架

總線一共分爲三大類:編程語言

片內總線:芯片內部各部件之間的數據傳輸,例如CPU內控制器、運算器和各個寄存器之間的信息傳輸

系統總線:CPU和主存、CPU和接口之間的信息傳輸。
數據總線:(Data Bus)爲雙向線,用於實如今CPU、存儲器、I/O接口之間的數據傳送;
數據總線的寬度等於計算機的字長
地址總線:(Address)爲單向線,用於傳送CPU所要訪問的存儲單元和I/O端口的地址信息。地址總線的位數決定了系統所能直接訪的問存儲空間的容量。

控制總線:(Control Bus)爲雙向線,用於控制總線上的操做和數據傳送的方向;實現微處理器與外部邏輯部件之間的同步操做。
外部總線:
鏈接外部設備,如SCSI,IDE,USB(屬於串口)

機器數的表示與編碼
1.原碼錶示法:

最高位表示符號,"0正,1負",其它n位表示數值的絕對值-0=1 0000000 例如: 設機器字長爲8位,求X1=0.1011B,X2=-0.1011B的原碼錶示 [x1]=0 1011000 [X2]=1 1011000 設機器字長爲8位,求X3=1011B,X4=-1011B的原碼錶示 [X3]=0 0001011 [X4]=1 0001011 

2.反碼錶示法:

正數的反碼與其原碼相同,負數的反碼是對其原碼符號位不變其它位取反。
-0的反碼=1 1111111 

3.補碼錶示法:

正數的補碼與原碼相同,負數的補碼,由其原碼符號位不變,其它位取反,末尾位加1求得。 在計算機系統中,存儲有符號整數時,用該整數的補碼進行存儲,0的原碼、補碼都是0。 

4.移碼錶示法:

[X補]求[X移]的規則:數值位不變,符號位取反 浮點數的階碼部分通常採用整數形式的移碼錶示。 0的移碼對0的補碼取反=1 0000000 

機器數的運算

1.算數運算

補碼運算的公式:
[X補]+[Y補]=[X+Y補] [X補-Y補]=[X補]+[-Y補] [Y補]-->[-Y補]:包含符號位,各位取反,末尾加1 

2.溢出的概念

兩正數相加,變負數,上溢(大於機器所能表示的最大數) 兩負數相加,變正數,下溢(小於機器所能表示的最小數) 

微型計算機的工做過程
微型計算機的五大部分相互配合,協同工做。根據馮.諾依曼的設計,計算機應能自動執行程序,執行程序又歸結爲逐條執行指令,分爲如下五個步驟:

1.取指令:從存儲器某個地址單元中取出要執行的指令送到指令寄存器暫存 2.分析指令:把保存在指令寄存器中的指令送到指令譯碼器中,譯出該指令對應的微操做信號,控制各個部件的操做 3.取操做數:若是須要,發出取數據命令,到存儲器取出須要的操做數 4.執行指令:根據指令譯碼,向各個部件發出相應控制信號,完成指令規定的各類操做 5.保存結果:若是須要保存計算結果,則把結果保存到指定的存儲器單元中。 完成一條指令所須要的時間稱爲指令週期。 一個指令週期每每包含多個總線週期,一個總線週期又包含多個時鐘週期,時鐘週期是計算機中最小的時間單位。 

馮.諾依曼計算機的基本設計思想

採用存儲程序的方式,編制好的程序和數據存放在同一存儲器中,
計算機能夠在無人干預的狀況下自動完成逐條取出指令和執行指令的任務;
在機器內部,指令和數據均以二進制碼錶示,指令在存儲器中按執行順序存放

"存儲程序控制"的概念

程序輸入到計算機中,存儲在內存儲器中(存儲原理),在運行時,控制器按地址順序取出存放在內存儲器中的指令(按地址順序訪問指令),而後分析指令,執行指令的功能,遇到轉移指令時,則轉移到轉移地址,再按地址順序訪問指令(程序控制)。

 

 

https://www.kancloud.cn/wintry/python3/742476

十六位微處理器

 

8088/8086微處理器功能結構
1.總線接口部件(BIU)
(1)功能

從內存取指令送到指令隊列CPU執行指令時,
總線接口部件要配合執行部件爲指定的內存單元或者外設端口收發數據

(2)組成

4個段地址寄存器,即: CS,16位代碼段寄存器 DS,16位數據段寄存器 ES,16位附加段寄存器 SS,16位堆棧段寄存器 16位指令指針寄存器 20位地址加法寄存器 4/6字節的指令隊列緩衝器 

(3)BIU指令隊列和20位地址加法器做用

指令隊列,指令一個一個預先排隊等候傳喚,稱爲流水線技術
減小了CPU取指令等待的時間,提升了CPU的效率

加法寄存器用來產生20位地址 8086可用20位地址尋址1MB內存空間 但8086內部全部的寄存器都是16位的, 因此須要一個附加機構來根據16位寄存器提供的信息計算出20位的物理地址 這個機構就是20位的地址加法器 

2.執行部件(EU)
1.功能

從指令隊列中取出指令
對指令進行譯碼
發出相應的傳送數據或算數運算的控制信號
接收由總線接口部件傳來的數據,或把數據傳送到總線接口部件
進行算數運算

2.組成

AX,BX,CX,DX--既可做爲16位寄存器也可做爲8位寄存器, 分別爲AH、BH、CH、DH、AL、BL、CL、DL AX又稱爲累加器,8086指令系統許多指令都經過累加器動做來執行 AH爲16位累加器,AL爲8位累加器 

(2)四個專用寄存器

基址指針寄存器BP
堆棧指針寄存器SP
源變址寄存器SI
目的變址寄存器DI

(3)算數邏輯單元ALU
它是16位運算器,可用於8位或16位二進制算數和邏輯運算,也可按指令的尋址方式計算尋址寄存器所需的16位偏移量。
(4)數據暫存運算器
協助ALU完成運算,暫存參加運算的數據
(5)EU控制電路。

從指令隊列取出指令操做碼
經過電路譯碼,發出相應控制命令
控制ALU的數據的流向。

若是是運算操做,操做數通過暫存寄存器送入ALU
運算結果通過ALU數據總線送到相應寄存器,
同時標誌寄存器PSW根據運算結果改變狀態

(6)標誌寄存器

標誌寄存器共有16位其中7位未用。 其中6個標誌位反應CPU指令運行後的運行狀態信息 SF、ZF、PF、CF、AF、OF這些標誌位, 用於根據指令執行後的操做結果進行判斷轉移。 3個控制標誌:DF、IF、TF 程序員可經過指令設置控制標誌,有專門的標誌對控制標誌置0或置1 

寄存器結構
1.通用數據寄存器

ABCD-X、16位可用做8位寄存器,分高低位, AX做爲累加器 BX做爲基址寄存器 CX做爲計數寄存器 DX做爲數據寄存器 

2.指針變址寄存器

分爲兩個指針寄存器SP(stack pointer)、BP(base pointer) 和兩個變址寄存器SI(source index)、DI(destination index) 這組寄存器一般用來存放存儲單元的16位偏移地址 偏移地址:相對起始地址的距離 

(1)指針寄存器

SP用來指示棧頂的偏移地址
BP存放位於堆棧段中一個數據區的"基址"的偏移量 

(2)變址寄存器

SI存放源操做數地址的偏移量
DI存放目標操做數地址的偏移量

3.段寄存器(segment registers)

CS、DS、SS、ES;代碼段、數據段、堆棧段、附加段
這些寄存器指明瞭一個特定的現行段,用來存放各段的段基址

4.指令指針

IP(instruction pointer)爲16位指令指針, ip的內容老是隻想BIU將要取的下一條指令代碼的16位偏移地址。 

8086指令隊列的做用

在執行指令的同時從內存中取了一條指令或下幾條指令,取來的指令放在指令隊列中這樣它就不須要象以往的計算機那樣讓CPU輪番進行取指和執行的工做,從而提升CPU的利用率。

8086/8088CPU有哪幾個狀態標誌位,有哪幾個控制標誌位?其意義各是什麼?

狀態標誌位有6個:ZF、SF、CF、OF、AF、PF。
其意思是用來反映指令執行的特徵,一般是由CPU根據指令執行結果自動設置的;
控制標誌位有3個:DF、IF、TF。
它是由程序經過執行特定的指令來設置的,以控制指令的操做方式。

8086/8088微處理器內部有哪些寄存器,他們的主要做用是什麼?

執行部件有8個16位寄存器,AX、BX、CX、DX、SP、BP、DI、SI,
AX、BX、CX、DX通常做爲通用數據寄存器。
SP爲堆棧指針存器
BP、DI、SI在間接尋址時做爲地址寄存器或變址寄存器。
總線接口部件設有段寄存器CS、DS、SS、ES和指令指針寄存器IP。
段寄存器存放段地址,與偏移地址共同造成存儲器的物理地址。
IP的內容爲下一條將要執行指令的偏移地址,與CS共同造成下一條指令的物理地址。

INTR、INTA、NMI、ALE、HOLD、HLDA引腳的名稱

INTR 可屏蔽請求信號
INTA 中斷請求信號
NMI 可屏蔽中斷請求信號
ALE 地址鎖存容許信號
HOLD 總線請求信號
HLDA 總線請求響應信號

什麼是中斷?什麼是中斷向量?中斷向量表的地址範圍?

中斷就是CPU在執行當前程序時因爲內外部事件引發CPU暫時中止當前正在執行的程序而轉向執行請求CPU暫時中止的內外部事件的服務程序,該程序處理完後又返回繼續執行被中止的程序;中斷向量是中斷處理子程序的入口地址;地址範圍是00000H-003FFH。

中斷向量表的功能是什麼?若中斷向量號分爲1AH和20H,則他們的中斷向量在中斷向量表的什麼位置上?

中斷向量表的功能是當中斷源發出中斷請求時,便可查找該表,找出其中斷向量,就可轉入相應的中斷服務子程序。1AH在中斷向量表的位置是1AH×4=68H在中斷向量表0000H:0068H處;20H在中斷向量表的位置是80H在中斷向量表0000H:0080H處。

一般解決中斷優先級的方法有哪幾種?

3種 軟件查詢肯定優先級 硬件優先級排隊電路肯定優先級 中斷屏蔽接口電路 

CPU響應可屏蔽中斷的條件是什麼?

(1)CPU必須處於開中斷狀態IF=1
(2)CPU現行指令執行結束
(3)沒有其餘優先級高的中斷請求。
(沒有內部中斷,沒有非屏蔽中斷,沒有總線請求)

以可屏蔽中斷爲例,說明一次完整的中斷過程主要包括哪些環節?

中斷請求:外設經過硬件信號的形式、向處理器引腳發送有效請求信號。
中斷響應:在知足必定條件時,處理器進入中斷響應總線週期。
關中斷:處理器在響應中斷後會自動關閉中斷。
斷點保護:處理器在響應中斷後將自動保護斷點地址。
中斷源識別:處理器識別出當前到底是哪一個中斷源提出了請求,
並明確與之相應的中斷服務程序所在主存位置。
現場保護:對處理器執行程序有影響的工做環境(主要是寄存器)進行保護。
中斷服務:處理器執行相應的中斷服務程序,進行數據傳送等處理工做。
恢復現場:完成中斷服務後,恢復處理器原來的工做環境。
開中斷:處理器容許新的可屏蔽中斷。
中斷返回:處理器執行中斷返回指令,程序返回斷點繼續執行原來的程序。

在中斷響應過程當中,8086往8259A發的兩個INTA信號分別起什麼做用?

在中斷響應過程當中,CPU向8259A的INTR引腳發2個負脈衝。 做用: 第一個負脈衝通知8259A ,CPU容許中斷請求,要求送中斷類型; 第二個負脈衝,8259傳輸中斷類型碼。

 

https://www.kancloud.cn/wintry/python3/742477

8086指令系統_尋址

 

彙編語言指令由操做碼和操做數兩部分組成。

操做碼說明指令的功能,即計算機要執行的具體操做
如:傳送、移位、運算等,是指令中不可缺乏的組成部分
操做數是指令執行的參與者,即各類操做的對象。
有些指令不須要操做數,有些指令有一個或兩個操做數。
有一個操做數的叫單操做數,有兩個操做數的叫雙操做數。

操做碼   目的操做數,源操做數 MOV EAX,00401000 

要指令執行,就要找到指令中的操做數,
要找到操做數,就要找到存放操做數的地址,
尋找指令中的操做數地址的方式叫作尋址方式;

全七類尋址方式:

1.當即尋址
操做數以字節形式緊跟在操做碼後邊
經常使用於給CPU中的寄存器或存儲單元賦值
當即數只能用做源操做數,不能做爲目的操做數。

例子:

MOV AL,56H 將當即數56H,送入8位寄存器AL MOV AX,1234H 將16位當即數1234H,送16位寄存器AX 

2.寄存器尋址
操做數存放在CPU的寄存器中,寄存器能夠是16位也能夠是8位
不用執行尋找操做數的總線週期,執行速度最快。
MOV AX,BX

3.存儲器尋址
操做數放在存儲器中,除代碼段以外的全部段數據。
這種存儲方式中,指令給出的是存放該操做數的存儲單元的地址
或產生該存儲單元地址的表達試。

CPU執行指令時,首先根據操做數字段提供的地址信息,由
執行單元EU計算出有效地址EA,再由總線接口單元BIU
根據物理地址公式"PA=段首地址X10H+有效地址"計算出物理地址
而後到物理地址對應的內存單元取出操做數,執行對該數的操做

存儲器尋址根據計算偏移地址的方法不一樣分爲如下5種
(1)直接尋址
這種尋址方式是從存儲器中尋找操做數最簡單的一種,
指令中直接給出的是該操做數在存儲器中的有效地址;其物理地址爲:
PA=段首地址X10H+EA(段首地址默認使用DS段寄存器,EA爲指令中給出的有效地址)

例子:
MOV AX,[2000H]

若操做數不在數據段,則應在指令中使用段跨越前綴,指明使用的數據在哪個段
例如:
MOV AX,ES:[2000H]
該指令將物理地址爲PA=(ES)X10H+2000H單元的值送AX

(2)寄存器間接尋址
操做數的有效地址由指令中指定的寄存器BX,BP,SI或DI的內容指定。
可分爲下面兩種狀況

①SI,DI或BX寄存器間接尋址,一般操做數實在數據段DS中,所以,
他們的物理地址是PA=(DS)X10H+EA

例:
MOV AX,[BX]
設(DS)=2000H,(BX)=1000H,則該操做數的物理地址爲:
PA=2000HX10H+1000H=21000H
這條指令的執行結果是把內存單元21000H中的數據送到AX寄存器中

②如果寄存器間接尋址,則該操做數在堆棧段SS中,即以堆棧段寄存器SS
與BP組合造成操做數的物理地址:PA=(SS)X10H+(BP)

例:
MOV BX,[BP]
設(SS)=1000H,(BP)=1500H,則PA=1000Hx10H+1500H=11500H
該操做數把11500H存儲單元的內容送到BX寄存器

(3)寄存器相對尋址
這種尋址方式的操做數存放在存儲器中的內存單元中,
是以基址寄存器(BX或BP)或變址寄存器(DI或SI)的內容爲基地址
而後在這個地址上加上8位或16位的位移量Disp,造成真正操做數的有效地址EA

當寄存器爲BX、SI、DI時,用段寄存器DS的內容做爲段基地址,則物理地址:
PA=(DS)X10H+(BX)/(SI)/(DI)+Disp8/Disp16

若寄存器爲BP,則段寄存器SS的內容做爲段首地址,則物理地址爲:
PA=(SS)X10H+(BP)+Disp8/Disp16

例:
MOV DI,[BX+2]

(4)基址變址尋址
操做數存放在內存單元中,其偏移地址是基址寄存器的內容加上變址寄存器的內容之和。

若基址寄存器爲BX,則段寄存器爲DS;
若基址寄存器爲BP,則段寄存器爲SS;

則操做數物理地址爲:

PA=(DS)X10H+(BX)+(SI)/(DI) 或 PA=(SS)X10H+(BP)+(SI)/(DI) MOV DX,[BP][SI] 

(5)相對基址變址尋址
操做數存放在內存單元中,其中有效地址由指令指定的基址寄存器加變址寄存器的內容在加上指令中的8位或16位偏移量Disp獲得,

其中物理地址爲:

PA=(DS)X10H+(BX)+(SI)/(DI)+Disp 或 PA=(SS)X10H+(BP)+(SI)/(DI)+Disp 

例:





MOV AX,MAS[BX][SI] ;MAS爲符號地址 MOV DX,5[BX][DI] ;將偏移地址爲5+(BX)+(DI)所指的單元的值送D

https://www.kancloud.cn/wintry/python3/742484

標誌寄存器

 

6個狀態標誌位的功能分別敘述以下:

CF(Carry Flag)——進位標誌位。

當執行一個加法(或減法)運算,使最高位產生進位(或借位)時 CF爲1,則爲0。 

PF(Parity Flag)——奇偶標誌位。

該標誌位反映運算結果中1的個數是偶數仍是奇數。 當指令執行結果的低8位中含有偶數個1時 PF=1;不然PF=0。 

AF(Auxiliary carry Flag)——輔助進位標誌位。

當執行一個加法(或減法)運算,使結果的低4位向高4位有進位(或借位)時, AF=1;不然AF=0。 

ZF(Zero Flag)——零標誌位。
若當前的運算結果爲零,ZF=1;不然ZF=0。

SF(Sign Flag)——符號標誌位。
它和運算結果的最高位相同。

OF(Overflow Flag)——溢出標誌位。
當補碼運算有溢出時,OF=1;不然OF=0。


3個控制標誌位用來控制CPU的操做,由指令進行置位和復位。

DF(Direction Flag)——方向標誌位。

它用以指定字符串處理時的方向,
當該位置「1」時,字符串以遞減順序處理,即地址以從高到低順序遞減。 反之,則以遞增順序處理。 

IF(Interrupt enable Flag)——中斷容許標誌位。

它用來控制8086是否容許接收外部中斷請求。 若IF=1,8086能響應外部中斷,反之則不響應外部中斷。 注意:IF的狀態不影響非屏蔽中斷請求(NMI)和CPU內部中斷請求 

TF(Trap Flag)——跟蹤標誌位。

它是爲調試程序而設定的陷阱控制位。
當該位置「1」時,8086 CPU處於單步狀態, 此時CPU每執行完一條指令就自動產生一次內部中斷。 當該位復位後,CPU恢復正常工做。

 https://my.oschina.net/clownfish/blog/142328

8086彙編中的標識寄存器叫flag。16位每一位都標識不同的含義,

15 14 13 12 11(OF) 10(DF) 9(IF) 8(TF) 7(SF) 6(ZF) 5 4(AF) 3 2(PF) 1 0(CF)

以上flag寄存器中各個位數表示的狀況。在8086cpu中只用到了0,2,4,6,7,8,9,10,11這9個位數,其餘的位數沒有任何意義。

CF Carry Flag ,進位標誌位 在進行無符號運算的狀況下,它記錄了運算結果的最高位有效位像更高位的進位值,或從更高位的借位值 CY(carry yes 進位) NC(No carry 未進位)
PF Parity Flag    奇偶標誌位 相關指令執行後,其結果所在bit位中1的個數是奇數或偶數,若是1個個數爲偶數,則pf=1,爲基數則pf=0 PE(parity even 偶) PO(parity odd 奇數)
AF Auxiliary Flag 輔助進位   AC(assistant carry進位) NA(no assistant carry 無進位)
ZF Zero Flag 零標誌位 相關指令執行後,其結果是否爲零,若是結果爲零則zf=1 若是結果不爲零則zf=0 ZF(zero等於零) NZ(no  zero不等於零)
SF Sign Flag 符號標識位 相關指令執行後,其結果是否爲負,若是爲負,則sf=1若是不爲負數 則sf=0 NG(negative)負 PL(plus 正)
TF Trap Flag 追蹤標誌 當追蹤標誌TF被置爲1時,CPU進入單步執行方式,即每執行一條指令,產生一個單步中斷請求。這種方式主要用於程序的調試。指令系統中沒有專門的指令來改變標誌位TF的值,但程序員可用其它辦法來改變其值。    
IF Interrupt Flag  中斷標誌位   EI(enable interrupt許可) DI(disable interrupt 禁止)
DF Direction Flag  方向標誌位   DN(Down減小) UP(UP增長)
OF Overflow Flag 溢出標誌位 在進行有符號數運算的狀況下,運算結果是否溢出,若是發生溢出,則of=1,未發生溢出 of=0 OV(overflow溢出) NV(no overflow未溢出)
指令 含義 檢測的相關標識位
je 等於則轉移(equal) zf=1
jne 不等於則轉移(not equal) zf=0
jb 低於則轉移(below) cf=1
jnb 不低於則轉移(not below) cf=0
ja 高於則轉移(above ) cf=0 && zf=0
jna 不高於則轉移(not above) cf=1 && zf=1

 

 

 

彙編語言, 即第二代計算機語言,用一些容易理解和記憶的字母,單詞來代替一個特定的指令,好比:用「ADD」表明數字邏輯上的加減,「 MOV」表明數據傳遞等等,經過這種方法,人們很容易去閱讀已經完成的程序或者理解程序正在執行的功能,對現有程序的bug修復以及運營維護都變得更加簡單方便。當計算機的硬件不認識字母符號,這時候就須要一個專門的程序把這些字符變成計算機可以識別的二進制數。由於彙編語言只是將機器語言作了簡單編譯,因此並無根本上解決機器語言的特定性,因此彙編語言和機器自身的編程環境息息相關,推廣和移植很難,可是仍是保持了機器語言優秀的執行效率,由於他的可閱讀性和簡便性,彙編語言到如今依然是經常使用的編程語言之一。 [2]  彙編語言不像其餘大多數的程序設計語言同樣被普遍用於程序設計。在今天的實際應用中,它一般被應用在底層,硬件操做和高要求的程序優化的場合。驅動程序、嵌入式操做系統和實時運行程序都須要彙編語言。 [1] 

https://baike.baidu.com/item/彙編語言/61826

 

機器語言

計算機的硬件做爲一種電路元件,它的輸出和輸入只能是有電或者沒電,也就是所說的高電平和低電平,因此計算機傳遞的數據是由「0」 和「1」組成的二進制數,因此說二進制的語言是計算機語言的本質。計算機發明之初,人們爲了去控制計算機完成本身的任務或者項目,只能去編寫「0」、「 1」這樣的二進制數字串去控制電腦,其實就是控制計算機硬件的高低電平或通路開路,這種語言就是 機器語言。直觀上看,機器語言十分晦澀難懂,其中的含義每每要經過查表或者手冊才能理解, 使用的時候很是痛苦,尤爲當你須要修改已經完成的程序時,這種看起來無序的機器語言會讓你無從下手,也很難找到程序的錯誤。並且,不一樣計算機的運行環境不一樣,指令方式操做方式也不盡相同,因此當你在這種機器語言就有了特定性,只能在特定的計算機上執行,而一旦換了機器就須要從新編程,這極大的下降了程序的使用和推廣效率。但因爲機器語言具備特定性,完美適配特定型號的計算機,故而運行效率遠遠高過其餘語言。機器語言,也就是第一代編程語言。  [2]  
     

彙編語言

不難看出機器語言做爲一種編程語言, 靈活性較差可閱讀性也不好,爲了減輕機器語言帶給軟件工程師的不適應,人們對機器語言進行了升級和改進:用一些容易理解和記憶的字母,單詞來代替一個特定的指令。經過這種方法,人們很容易去閱讀 已經完成的程序或者理解程序正在執行的功能,對現有程序的bug修復以及運營維護都變得更加簡單方便,這種語言就是咱們所說的彙編語言, 即第二代計算機語言。  [2]  
比起機器語言,彙編語言具備更高的機器相關性,更加便於記憶和書寫,但又同時保留了機器語言高速度和高效率的特色。彙編語言還是面向機器的語言,很難從其代碼上理解程序設計意圖,設計出來的程序不易被移植,故不像其餘大多數的高級計算機語言同樣被普遍應用。因此在高級語言高度發展的今天,它一般被用在底層,一般是程序優化或硬件操做的場合。  [3]  
     

高級語言

在編程語言經歷了機器語言,彙編語言等更新以後,人們發現了限制程序推廣的關鍵因素——程序的可移植性。須要設計一個可以不依賴於計算機硬件,可以在不一樣機器上運行的程序。這樣能夠免去不少編程的重複過程,提升效率,同時這種語言又要接近於 數學語言或人的 天然語言。在計算機還很稀缺的50年代,誕生了第一個高級編程語言。當時計算機的造價不菲,可是天天的計算量有有限,如何有效的利用計算機有限的計算能力成爲了當時人們面對的問題。同時,由於資源的稀缺, 計算機的運行效率也成爲了那個年代工程師追尋的目標。爲了更高效的使用計算機,人們設計出了高級編程語言,來知足人們對於高效簡的編程語言的追求。  [2]  
 

語言組成

因爲彙編指令系統龐大,於是需構建指令系統體系,其指令數量龐大,格式複雜,可記憶性差等。指令中最難的是指令所支持的 尋址方式,其實質就是指令中操做數如何獲取。對於處理器而言,就是如何找到他所需的數據。但對於計算機底層的彙編語言而言,這種尋址方式將涉及大量的計算存儲格式,與 複雜的存儲管理方式緊密相關,於是難以理解。最後,彙編指令還關係到如何影響標誌位,但處理器標誌位很是複雜,於是對其機制掌握就比較困難。  [4]  
     

傳送指令

包括通用數據傳送指令 MOV、條件傳送指令CMOV cc、堆棧操做指令PUSH/PUSHA/PUSHAD/POP/POPA/POPAD、交換指令XCHG/XLAT/BSWAP、地址或 段描述符選擇子傳送指令 LEA/ LDS/LES/ LFS/LGS/ LSS等。  [1]   
     

邏輯運算

這部分指令用於執行算術和邏輯運算,包括加法指令ADD/ ADC、減法指令 SUB/ SBB、加一指令 INC、減一指令 DEC、比較操做指令CMP、乘法指令 MUL/ IMUL、除法指令 DIV/IDIV、符號擴展指令 CBW/CWDE/CDQE、 十進制調整指令 DAA/ DAS/ AAA/AAS、 邏輯運算指令NOT/ AND/OR/XOR/TEST等。  [1]   
     

移位指令

這部分指令用於將寄存器或內存操做數移動指定的次數。包括邏輯左移指令 SHL、邏輯右移指令SHR、算術左移指令 SAL、算術右移指令SAR、循環左移指令 ROL、循環右移指令 ROR等。  [1]   
     

位操做

這部分指令包括位測試指令 BT、位測試並置位指令BTS、位測試並復位指令 BTR、位測試並取反指令BTC、位向前掃描指令 BSF、位向後掃描指令BSR等。  [1]   
     

控制轉移

這部分包括無條件轉移指令 JMP、條件轉移指令 Jcc/JCXZ、循環指令 LOOP/LOOPE/LOOPNE、過程調用指令 CALL、子過程返回指令 RET、中斷指令 INTn、INT三、 INTOIRET等。  [1]   
     

串操做

這部分指令用於對數據串進行操做,包括串傳送指令MOVS、串比較指令 CMPS、串 掃描指令SCANS、串加載指令 LODS、串保存指令 STOS,這些指令能夠有選擇地使用 REP/REPE/REPZ/REPNE和REPNZ的前綴以連續操做。  [1]   
     

輸入輸出

這部分指令用於同外圍設備交換數據,包括端口輸入指令IN/INS、端口輸出指令OUT/OUTS。  [1]  
 

https://www.kancloud.cn/wintry/python3/742485

 

經常使用匯編指令

 

彙編語言指令大體分爲如下幾類

1、傳送類指令
2、算數運算類指令
3、位操做指令
4、串操做指令
5、控制轉移類指令
6、處理器控制類指令
7、彙編指令僞指令


1、傳送類指令
1.數據傳送指令
(1) MOV 目的操做數,源操做數
將源操做數送到目的操做數,目的和源的數的長度要相同,不然會長度不匹配
(2)XCHG 傳送指令
XCHG 目的操做數,源操做數 //把源和目的操做數交換數值
2.有效地址傳送指令LEA

LEA 目的操做數,源操做數
把源操做數的偏移地址送目的操做數,
源操做數必須是一個內存操做數,
目的操做數必須是16位通用寄存器 

3.堆棧指針操做指令
堆棧是一塊特殊的存儲器區域,這塊區域是以先進後出的方式工做,系統爲此提供了特殊的指針SP,和段寄存器SS
主要特色是:
(1)堆棧是以字方式操做的
(2)壓入堆棧。
①先修改指針:SP=SP -2
②再存入一個字
(3)彈出堆棧。
①先彈出一個字
②再修改指針:SP=SP +2

(4)入棧指令PUSH
格式:PUSH 操做數
該指令爲數據入棧指令
即將操做數指定的一個字節的內容傳送至SP所指的棧頂
尋址方式有寄存器尋址(段寄存器SS除外)和存儲器尋址,
不能用當即數做操做數。
該指令不影響標誌位。

過程:
首先,堆棧SP=SP-2
而後,操做數的高位字節——>存入((SP)+1)單元中
操做數的低位字節——>送入(SP)

(5)出棧指令:POP
POP 操做數
將SP所指的棧頂內容傳送至操做數指定的一個字。

尋址方式有:
寄存器尋址(段寄存器SS除外)和存儲器尋址
不能用當即數做操做數。
該指令不影響標誌位。

過程:
首先堆棧((SP)+1)單元字節——>操做數的高字節位,
(SP)單元字節——>操做數的低位字節。
而後SP=SP-2
4.輸入輸出指令
(1)IN 輸入指令

IN AL,N ; (N)——>AL IN AX,N ; (N+1:N)——>AX IN AL,63H ; 將端口地址爲63H的一個字節內容輸入到AL IN AX,55H ;將兩個相鄰端口地址58H和59H的16位數據輸入到AX 

(2)OUT 輸出指令

OUT N,AL ;(AL)字節——>N端口地址的單元中 OUT N,AX ;(AX)字——>N+1和N端口地址的單元中 OUT 66H,AL ;將AL內容送端口地址66H的單元中 OUT 66H,AX ;將AX內容送66H和67H端口地址的單元中 

!注意:

在彙編語言中,端口地址小於256(十六進制00H~FFH)時
能夠直接在指令中寫出端口地址
若是端口地址大於256,先將端口地址送入DX寄存器中,
而後在IN或OUT指令中用DX表明端口地址。


2、算數運算類指令
參加運算的能夠是無符號數或帶符號數,帶符號的數以補碼的形式存放或參與運算
1.加法指令
(1)ADD 目的操做數,源操做數
目的操做數+源操做數——>目的操做數
(2)ADC帶進位的加法指令
ADC 目的操做數,源操做數
目的操做數+源操做數+CF——>目的操做數
例子:

MOV AH,0 ;0——>AH MOV AL,92H ;92H——>AL ADD AL,86H ;92H+86H=18H——>AL,CF=1 ADC AH,0 ;(AH)+0+CF=0+0+1=1——>AH,即01H=AH 

(3)INC 加|指令
INC 操做數 //操做數加1,結果送操做數
操做數能夠是任意一個8或16位的通用寄存器或存儲單元,不能是當即數
指令中操做數看成無符號數時,主要用於計數器計數或修改指針地址的值。
如:

INC DI   ;(DI)=DI+1 INC CX ;(CX)=CX+1 

說明:除了指令INC對標誌位CF不影響外,其它加法指令對標誌位的影響以下

①CF:兩個數相加,最高有效位有進位時,即字節運算超出無符號輸的範圍
0~255,字運算超出無符號數的範圍0~65535時,CF=1,不然CF=0.
故兩個無符號數相加時,可用CF值來判斷是否超出了無符號數的表示範圍
若是CF=1表示此無符號數加法運算結果發生了溢出。
②PF:運算結果以二進制數表示時,若"1"的個數爲偶數時PF=1,不然PF=0
③AF:運算中D3向D4有進位時,AF=1,不然爲0
④ZF:運算結果爲0時,ZF=1;不然ZF=0
⑤SF:運算結果最高位爲1時,SF=1,不然爲0
⑥OF:當兩個操做數的符號相同,而相加的結果的符號與操做數的符號相反時
OF=1,不然OF=0。該標誌位用來判斷帶符號數相加的溢出

例如:

ADD AL,30H ;(AH)+30H ——> AL ADD AX,3000H ;(AX)+3000H ——> AX ADD BX,[SI] ;(BX)+((SI))——>BX 

2.減法指令
(1)SUB
SUB 目的操做數,源操做數
目的操做數=目的操做數-源操做數
(2)SBB 帶錯位的減法指令
SBB 目的操做數,源操做數
目的操做數=目的操做數-源操做數-CF
(3)DEC 減1指令 格式:DEC 操做數
DEC DI ;DI=(DI)-1
(4)NEG 求補指令

NEG 操做數   //0-操做數的內容後結果回送操做數 MOV DI,05H NEG DI ;DI=0-(DI)=0-05H=0FBH 

(5)CMP 比較指令
CMP 目的操做數,源操做數
執行時目的操做數與源操做數相減,只根據結果設置標誌位
操做數均保持原值不變
3.類型擴展指令
爲了解決操做數長度的匹配,有時須要把數據類型進行擴展。
主要有把字節擴展成字,把字擴展成雙字

CBW:字節擴展成字
CWD:字擴展成雙字

例子:
正數的擴展

MOV AL,52H CBW ;執行指令後,AX=0052H CWD ;執行指令後,DX=0000H,AX=0052H 

負數的擴展

MOV AL,86H CBW ;執行指令後,AX=FF86H CWD ;執行指令後,DX=FFFFH,FF86H 

4.乘法指令

MUL :無符號數乘法
IMUL:帶符號數乘法

目的操做數必須是累加器,沒必要在指令中寫出。
例子:
無符號數乘法

MOV AL,05H MOV BL,06H MUL BL //執行結果AX=30=001EH 

有符號數乘法

MOV AL,-5 MOV BL,+6 IMUL BL //AX=-30=FFE2H 

5.除法指令
DIV:無符號除法

SRC(源操做數)爲字節時,AL=AX/SRC的商,AH=AX/SRC的餘數 SRC爲字時:AX=(DX,AX)/SRC的商,DX=(DX,AX)/SRC的餘數 

商和餘數都是無符號數。
IDIV:有符號除法
操做同上相似,目的操做數必須是累加器AX和DX,沒必要寫出。


3、位操做指令

AND 與運算. or 或運算. XOR 異或運算. NOT 取反. TEST 測試.(兩操做數做與運算,僅修改標誌位,不回送結果). SHL 邏輯左移. SAL 算術左移.(=SHL) SHR 邏輯右移. SAR 算術右移.(=SHR) ROL 循環左移. ROR 循環右移. RCL 經過進位的循環左移. RCR 經過進位的循環右移. 以上八種移位指令,其移位次數可達255次. 移位一次時, 可直接用操做碼. 如 SHL AX,1. 移位>1次時, 則由寄存器CL給出移位次數. 如 MOV CL,04 SHL AX,CL 

4、串操做指令

DS:SI 源串段寄存器 :源串變址. ES:DI 目標串段寄存器:目標串變址. CX 重複次數計數器. AL/AX 掃描值. D標誌 0表示重複操做中SI和DI應自動增量; 1表示應自動減量. Z標誌 用來控制掃描或比較操做的結束. MOVS 串傳送. ( MOVSB 傳送字符. MOVSW 傳送字. MOVSD 傳送雙字. ) CMPS 串比較. ( CMPSB 比較字符. CMPSW 比較字. ) SCAS 串掃描. 把AL或AX的內容與目標串做比較,比較結果反映在標誌位. LODS 裝入串. 把源串中的元素(字或字節)逐一裝入AL或AX中. ( LODSB 傳送字符. LODSW 傳送字. LODSD 傳送雙字. ) STOS 保存串. 是LODS的逆過程. REP 當CX/ECX<>0時重複.,也就是直到CX=0時結束 REPE/REPZ 當ZF=1或比較結果相等,且CX/ECX<>0時重複. REPNE/REPNZ 當ZF=0或比較結果不相等,且CX/ECX<>0時重複. REPC 當CF=1且CX/ECX<>0時重複. REPNC 當CF=0且CX/ECX<>0時重複. 

5、控制轉移類指令
1>無條件轉移指令 (長轉移)

JMP 無條件轉移指令
CALL 過程調用
RET/RETF過程返回. 

2>條件轉移指令 (短轉移,-128到+127的距離內)

( 當且僅當(SF XOR OF)=1時,OP1<OP2 ) JA/JNBE 不小於或不等於時轉移. JAE/JNB 大於或等於轉移. JB/JNAE 小於轉移. JBE/JNA 小於或等於轉移. 以上四條,測試無符號整數運算的結果(標誌C和Z). JG/JNLE 大於轉移. JGE/JNL 大於或等於轉移. JL/JNGE 小於轉移. JLE/JNG 小於或等於轉移. 以上四條,測試帶符號整數運算的結果(標誌S,O和Z). JE/JZ 等於轉移. JNE/JNZ 不等於時轉移. JC 有進位時轉移. JNC 無進位時轉移. JNO 不溢出時轉移. JNP/JPO 奇偶性爲奇數時轉移. JNS 符號位爲 "0" 時轉移. JO 溢出轉移. JP/JPE 奇偶性爲偶數時轉移. JS 符號位爲 "1" 時轉移. 

3>循環控制指令(短轉移)

LOOP CX不爲零時循環. LOOPE/LOOPZ CX不爲零且標誌Z=1時循環. LOOPNE/LOOPNZ CX不爲零且標誌Z=0時循環. JCXZ CX爲零時轉移. JECXZ ECX爲零時轉移. 

4>中斷指令

INT 中斷指令
INTO 溢出中斷
IRET 中斷返回

6、處理器控制類指令
處理器控制類指令只能完成對CPU的簡單控制功能。
共有12條
對標誌位操做

CLC(進位位置0指令) CMC(進位位求反指令) STC(進位位置爲1指令) CLD(方向標誌置1指令) STD(方向標誌位置1指令) CLI(中斷標誌置0指令) STI(中斷標誌置1指令) 

同步控制

WAIT(等待)
ESC(交權)
LOCK(封鎖總線)

其餘

NOP(無操做)
HLT(暫停)

7、彙編指令僞指令



DW 定義字(2字節). PROC 定義過程. ENDP 過程結束. SEGMENT 定義段. ASSUME 創建段寄存器尋址. ENDS 段結束. END 程序結束.

 

https://baike.baidu.com/item/彙編指令

彙編指令是彙編語言中使用的一些操做符和助記符,還包括一些僞指令(如assume,end)。用於告訴彙編程序如何進行彙編的指令,它既不控制機器的操做也不被彙編成機器代碼,只能爲彙編程序所識別並指導彙編如何進行。

數據傳輸

它們在 存儲器寄存器、寄存器和輸入輸出端口之間傳送數據。
1. 通用 數據傳送指令
MOV 傳送字或字節.
MOVSX 先符號擴展,再傳送.
MOVZX 先零擴展,再傳送.
PUSH 把字壓入 堆棧.
POP 把字彈出堆棧.
PUSHA 把AX,CX,DX,BX,SP,BP,SI,DI依次壓入 堆棧.
POPA 把DI,SI,BP,SP,BX,DX,CX,AX依次彈出 堆棧.
PUSHAD 把EAX,ECX,EDX,EBX,ESP,EBP,ESI,EDI依次壓入 堆棧.
POPAD 把EDI,ESI,EBP,ESP,EBX,EDX,ECX,EAX依次彈出 堆棧.
BSWAP 交換32位寄存器裏字節的順序
XCHG 交換字或字節.( 至少有一個 操做數爲寄存器, 段寄存器不可做爲操做數)
CMPXCHG 比較並交換 操做數.( 第二個操做數必須爲 累加器AL/AX/EAX )
XADD 先交換再累加.( 結果在第一個 操做數裏 )
XLAT 字節查錶轉換.
── BX 指向一張 256 字節的表的起點, AL 爲表的索引值 (0-255,即
0-FFH); 返回 AL 爲查表結果. ( [BX+AL]->AL )
2. 輸入輸出端口傳送指令.
IN I/O端口輸入. ( 語法: IN  累加器, { 端口號│DX} )
OUT I/O端口輸出. ( 語法: OUT {端口號│DX}, 累加器 )
輸入輸出端口由當即方式指定時, 其範圍是 0-255; 由 寄存器 DX 指定時,
其範圍是 0-65535.
3. 目的地址傳送指令.
LEA 裝入 有效地址.
例: LEA DX,string ;把 偏移地址存到DX.
LDS 傳送目標 指針,把指針內容裝入DS.
例: LDS SI,string ;把 段地址: 偏移地址存到DS:SI.
LES 傳送目標 指針,把指針內容裝入ES.
例: LES DI,string ;把 段地址: 偏移地址存到ES:DI.
LFS 傳送目標 指針,把指針內容裝入FS.
例: LFS DI,string ;把 段地址: 偏移地址存到FS:DI.
LGS 傳送目標 指針,把指針內容裝入GS.
例: LGS DI,string ;把 段地址: 偏移地址存到GS:DI.
LSS 傳送目標 指針,把指針內容裝入SS.
例: LSS DI,string ;把 段地址: 偏移地址存到SS:DI.
4. 標誌傳送指令.
LAHF 標誌寄存器傳送,把標誌裝入AH.
SAHF  標誌寄存器傳送,把AH內容裝入標誌寄存器.
PUSHF 標誌入棧.
POPF 標誌 出棧.
PUSHD 32位標誌入棧.
POPD 32位標誌 出棧.

算術運算

ADD 加法.
ADC 帶進位加法.
INC 加 1.
AAA 加法的ASCII碼調整.
DAA 加法的十進制調整.
SUB 減法.
SBB 帶借位減法.
DEC 減 1.
NEG 取補
CMP 比較.(兩 操做數做減法,僅修改標誌位,不回送結果).
AAS 減法的ASCII碼調整.
DAS 減法的十進制調整.
MUL 無符號乘法.
IMUL 整數乘法.
以上兩條,結果回送AH和AL(字節運算),或DX和AX(字運算),
AAM 乘法的ASCII碼調整.
DIV 無符號除法.
IDIV 整數除法.
以上兩條,結果回送:
商回送AL,餘數回送AH, (字節運算);
或 商回送AX,餘數回送DX, (字運算).
AAD 除法的ASCII碼調整.
CBW 字節轉換爲字. (把AL中字節的符號擴展到AH中去)
CWD 字轉換爲雙字. (把AX中的字的符號擴展到DX中去)
CWDE 字轉換爲雙字. (把AX中的字符號擴展到EAX中去)
CDQ 雙 字擴展. (把EAX中的字的符號擴展到EDX中去)

邏輯運算

AND 與運算.
or 或運算.
XOR 異或運算.
NOT 取反.
TEST 測試.(兩 操做數做與運算,僅修改標誌位,不回送結果).
SHL 邏輯左移.
SAL 算術左移.(=SHL)
SHR 邏輯右移.( 每位右移, 低位進 CF, 高位補 0)
SAR 算術右移.(每位右移, 低位進 CF, 高位不變)
ROL 循環左移.
ROR 循環右移.
RCL 經過進位的循環左移.
RCR 經過進位的循環右移.
以上八種移位指令,其移位次數可達255次.
移位一次時, 可直接用 操做碼. 如 SHL AX,1.
移位>1次時, 則由寄存器CL給出移位次數.
如 MOV CL,04
SHL AX,CL

串指令

DS:SI 源串 段寄存器 :源串 變址.
ES:DI 目標串 段寄存器:目標串 變址.
CX 重複次數計數器.
AL/AX 掃描值.
D標誌 0表示重複操做中SI和DI應自動增量; 1表示應自動減量.
Z標誌 用來控制掃描或比較操做的結束.
MOVS 串傳送.
( MOVSB 傳送字符. MOVSW 傳送字. MOVSD 傳送雙字. )
CMPS 串比較.
( CMPSB 比較字符. CMPSW 比較字. )
SCAS 串掃描.
把AL或AX的內容與目標串做比較,比較結果反映在標誌位.
LODS 裝入串.
把源串中的元素(字或字節)逐一裝入AL或AX中.
LODSB 傳送字符. LODSW 傳送字. LODSD 傳送雙字. )
STOS 保存串.
是LODS的逆過程.
REP 當CX/ECX<>0時重複.
REPE/REPZ 當ZF=1或比較結果相等,且CX/ECX<>0時重複.
REPNE/REPNZ 當ZF=0或比較結果不相等,且CX/ECX<>0時重複.
REPC 當CF=1且CX/ECX<>0時重複.
REPNC 當CF=0且CX/ECX<>0時重複.

程序轉移

1>無條件轉移指令 (長轉移)
JMP 無條件轉移指令
CALL 過程調用
RET/RETF過程返回.
2>條件轉移指令 (短轉移,-128到+127的距離內)
( 當且僅當(SF XOR OF)=1時,OP1<OP2 )
JA/JNBE 大於轉移
JAE/JNB 大於或等於轉移.
JB/JNAE 小於轉移.
JBE/ JNA 小於或等於轉移.
以上四條,測試 無符號整數運算的結果(標誌C和Z).
JG/JNLE 大於轉移.
JGE/JNL 大於或等於轉移.
JL/JNGE 小於轉移.
JLE/JNG 小於或等於轉移.
以上四條,測試帶符號整數運算的結果(標誌S,O和Z).
JE/JZ 等於轉移.
JNE/JNZ 不等於時轉移.
JC 有進位時轉移.
JNC 無進位時轉移.
JNO 不溢出時轉移.
JNP/JPO 奇偶性爲奇數時轉移.
JNS 符號位爲 "0" 時轉移.
JO 溢出轉移.
JP/JPE 奇偶性爲偶數時轉移.
JS 符號位爲 "1" 時轉移.
3>循環控制指令(短轉移)
LOOP CX不爲零時循環.
LOOPE/LOOPZ CX不爲零且標誌Z=1時循環.
LOOPNE/LOOPNZ CX不爲零且標誌Z=0時循環.
JCXZ CX爲零時轉移.
JECXZ ECX爲零時轉移.
4>中斷指令
INT  中斷指令
INTO 溢出中斷
IRET 中斷返回

其餘指令

僞指令

DB定義字節(1字節)
DW 定義字(2字節).
DD定義雙字(4字節)
PROC 定義過程.
ENDP 過程結束.
SEGMENT 定義段.
ASSUME 創建段 寄存器尋址.
ENDS 段結束.
END 程序結束.

控制指令

標誌處理指令 CLC(進位位置0指令)
CMC(進位位求反指令)
CLC(進位位置爲0指令)
STC(進位位置爲1指令)
CLD(方向標誌位置0指令)
STD(方向標誌位置1指令)
CLI(中斷標誌置0指令)
STI(中斷標誌置1指令)
NOP(無操做)
HLT(停機)
WAIT(等待)
ESC(換碼)
LOCK(封鎖)

 

 

 

 

 

[原創]【老劉談算法001】這位運算玩的真溜—strlen函數的彙編實現分析-『密碼算法』-看雪安全論壇 https://bbs.pediy.com/thread-229243.htm

;原函數做者爲Agner Fog,出處爲MASM32開發包,在此表示感謝。
;中文註釋修改&添加 By 老劉。
  
  
    .486
    .model flat, stdcall
    option casemap :none
  
    .code
  
  
OPTION PROLOGUE:NONE
OPTION EPILOGUE:NONE
  
align 4
  
StrLen proc item:DWORD
  
    mov     eax, [esp+4]            ;得到參數item,即字符串指針
    lea     edx, [eax+3]            ;edx=指針+3
    push    ebp                     ;備份ebp edi
    push    edi
    mov     ebp, 80808080h
  
  @@:     
  REPEAT 3
    mov     edi, [eax]              ;edi=讀4個字節
    add     eax, 4                  ;字符串指針指到下4個字節起始,即+4
    lea     ecx, [edi-01010101h]    ;ecx=四字節每一個字節-1
    not     edi                     ;edi=四字節邏輯取反
    and     ecx, edi                ;ecx=取反後的每一個字節和沒取反後-1的每一個字節進行邏輯與
    and     ecx, ebp                ;判斷每一個字節的二進制第8位是否爲1,爲1則說明原字節=0
    jnz     nxt                     ;若是出現了一個null異端,跳到nxt繼續判斷
  ENDM
  
    mov     edi, [eax]              ;和上面的同樣
    add     eax, 4                  
    lea     ecx, [edi-01010101h]    
    not     edi                    
    and     ecx, edi               
    and     ecx, ebp
    jz      @B                      ;若是沒有異端,回去上面循環,有的話都不用跳了,下面就是nxt
  
  nxt:
    test    ecx, 00008080h          ;測試null是否在前2個字節中
    jnz     @F
    shr     ecx, 16                 ;不在前2字節,ecx右移16個二進制位,即右移2字節,使原來的第三、4字節移位到一、2字節處。
    add     eax, 2                  ;字符串指針+2
  @@:
    shl     cl, 1                   ;第一個字節邏輯左移1位,若是第一個字節爲Null,則CF=1,不然即說明第二個字節爲Null
    sbb     eax, edx                ;eax=eax-edx-CF=eax-(item+3)-CF=字符串長度
    pop     edi
    pop     ebp
  
    ret     4
  
StrLen endp
  
OPTION PROLOGUE:PrologueDef 
OPTION EPILOGUE:EpilogueDef 
  
  
end

  

 
http://blog.luoyuanhang.com/2015/07/07/幾種基本彙編指令詳解/ 

##常見寄存器

寄存器 16位 32位 64位
累加寄存器 AX EAX RAX
基址寄存器 BX EBX RBX
計數寄存器 CX ECX RCX
數據寄存器 DX EDX RDX
堆棧基指針 BP EBP RBP
變址寄存器 SI ESI RSI
堆棧頂指針 SP ESP RSP
指令寄存器 IP EIP RIP

##彙編指令

##mov

  • movb(8位)、movw(16位)、movl(32位)、movq(64位)

  • 寄存器尋址:

    movl %eax, %edx

    eax -> edx

  • 當即數尋址:

    movl $0x123, %edx

    數字->寄存器

  • 直接尋址:

    movl 0x123, %edx

    直接訪問內存地址數據,edx = *(int32_t *)0x123;

  • 間接尋址:

    movl (%ebx), %edx

    %ebx 是個內存地址,(%ebx)指的是該地址中的數據,edx = *(int32_t*)ebx;

  • 變址尋址:

    movl 4(%ebx), %edx

    edx = *(int32_t*)(ebx+4);

##push & pull

###堆棧數據結構簡介

####做用:

  • 程序調用框架
  • 傳遞參數
  • 保存返回地址
  • 提供局部變量
  • ……

####結構:

image

  • 相關寄存器: esp, ebp

  • 相關操做: pop, push

    //創建被調用者函數的堆棧框架
    pushl %ebp
    movl %esp, %ebp
    
    //拆除框架
    movl %ebp, %esp
    popl %ebp
    ret

###push:壓棧

  • push %eax

    至關於:

    subl $4, %esp
    //棧頂指針減4
    movl %eax, (%esp)
    //%eax -> esp 地址

###pop:出棧

  • pop %eax

    至關於:

    movl (%esp), %eax
    addl %4, %esp
    //棧頂指針加4

##call&ret

###call

  • call 0x12345

    至關於:

    pushl %eip
    movl $0x12345, %eip
    //當前地址壓棧,存入新地址

###ret

  • 至關於:

    popl %eip
    //棧 -> eip

##enter&leave

###enter

push %ebp
movl %esp, %ebp
//將堆棧置空(棧上重堆)

###leave

movl %ebp, %esp
popl %ebp
//將堆棧置空(撤銷堆棧)

##例子:分析一段彙編代碼

pushl $8    ①
movl %ebp, %esp        ②
subl $4, %esp    ③
movl $8, (%esp)        ④
 
 
 
 中斷號有限,用一個或多箇中斷號來對應全部的系統調用

 

linux系統中斷流程

 

內核態               中斷向量表--->查找0x80--->0x80 中斷服務程序(system_call)--->調用--->系統調用表--->查表eax=2--->系統調用sys_fork

|

|                    ^                     |                                      |                     |用戶態 用戶代碼--->fork--->eax=2 int 0x80

相關文章
相關標籤/搜索