16位汇编第八讲指令第四讲
16位匯編第八講指令第四講
一丶串操作類指令
1.什么是串操作?
1.串操作指令是8086指令系統中比較獨特的一類指令,采用比較特殊的數據串尋址方式,在操作主存連續區域
的數據是,特別好用.因而比較常用
簡而言之,就是內存中的一段數據,拷貝/讀取/修改... 到另一塊另內存
重點掌握 MOVS STOS LODS CMPS SCAS REP
2.串操作的簡介
1.串操作指令的操作數,是駐村中連續存放的數據串(String 注意string表示串的意思)--也就是一段數據在內存中
是連續的,以字或者字節排列
2.串操作指令的操作對象是以字(Word)為單位的字串,或者字節(Byte)為單位的字節串--簡單理解就是我要操作
1個字節大小,還是兩個字節大小
3.串的操作
串的操作一般使用 SI(源寄存器)和 DI(目的寄存器),可以使用端超越DS:[SI]
或者目的寄存器 DI ES:[DI]
每次執行一次串操作,那么SI和DI則會自動修改,地址自增
當然地址自增是看方向標志的 DF 我們要想復制的時候,讓其內存自增復制,那么就用CLD讓方向初始為自增
否則 反向復制的話就用STD指令讓地址自減
4.串操作指令中的串傳送指令(MOVS)
作用:
把字節或者字操作數從內存的源地址,傳送到目的地址
分別有兩個指令,一個是字節串傳送,一個是字傳送
MOVSB (后綴b代表byte的意思) MOVSW(后綴w代表字的意思)
指令:
MOVSB ES:[DI] <- DS:[SI] 從si內存中取出一個字節的數據,復制到DI中
SI<-SI±1,DI<-DI±1 地址隨著方向標志自增1或者自減1
MOVSW ES:[DI] <- DS:[SI] 從si內存中取出一個字的數據,復制到DI中
SI<-SI±2,DI<-DI±2 地址隨著方向標志自增2或者自減2
使用例子:
主要是兩個花紅框的地方,意思是什么,第一個畫紅框的內容
1.定義一個源地址,里面的內容是HELLO 也就是內存的內容是Hello
2.定義一個目標地址,里面的內容是申請了100個字節,然后初始化為零
第二個畫紅框的內容
1.首先給si設置偏移這里使用lea設置的, 我們也可以寫成 mov si,offset g_szSrc,下面的目的也是一樣
2.給目的設置偏移
3.使用movsb,從si內從中取出一個字節,設置到目的內存中
可以看出,方向標志位默認是往下自增的,我并沒有使用CLD設置,所以SI 和DI復制完成后,內存就會自增
會C語言的請看這條注釋 : 在C語言中,這個命令就相當于 memcpy(內存拷貝)每次拷貝幾個字節,不懂匯編的濾過
當然我們可以使用 MOVSW 只不過一次拷貝兩個字節了.具體的自己手工嘗試.
5.串操作指令中的串存儲指令STOS(store string)
作用: 把AL或者AX數據傳送到目的地址
C語言的請看: 在C語言中,這條命令相當于 memset,清空的作用
這個就簡單了,把寄存器的數據,傳送到目的寄存器中,也就是 ES:[DI]中
ES:[DI]<-AL/AX
對于這里我說一下ES 和DS 上面我們使用的時候,并沒有使用段超越指令,為什么,因為我們的DI 和SI都是數據區了,
也就是說不用使用段超越了,否則你需要自己加,一般來說,ES和DS兩個段都是合并到一起的
STOSB,STOSW
分別對應兩條指令
STOSB 字節串存儲 ES[DI]<-AL,把AL的數據,放到DI中
按照方向標志,DI<-DI±1 自增或者自減1
STOSW 字串存儲: ES:[DI]<-Ax ,把AX中的數據,放到DI中
按照方向標志,DI<-DI±2 自增或者自減2
使用例子,字節串存儲
第一框,代碼是給al一個3,然后通過段存儲的命令,把3給DI存儲
反匯編單步調試,已經完成一個字節保存了,現在看下DI 06的偏移處是不是3
是3,完成了操作
STOSW 則是把AX中的數據,放到DI中,放兩個字節,也就是一個字,因為AX是16位寄存器.
具體自己測試即可.
6.串操作指令,串讀取LODS(load string)
作用:
把指定的主存單元的數據傳送給AL,或者AX
看到這里已經明白了吧,上面的是吧AL,或者AX中的內容存儲到DI中,這個則是讀取到DI中,唯一不同的則是從源寄存器中讀取(也就是SI)
LODSB 字節串讀取 AL<-DS:[SI] 按照方向標志,自增或者自減1 SI<-SI±1
LODSW 字讀取 AX<-DS:[SI] 按照方向標志,自增或者自減2 SI<-SI±2
使用例子:
現在可以看到AX中的值是0b46,而SI中的偏移加上段地址所在的物理地址是hello
我們使用了 字讀取,也就是讀取兩個字節,也就是說AX中的值會變為 he 這兩個字符的ASCII碼
具體的字節讀取,自己測試便知道了
7.串操作命令,串比較CMPS(compare string)
作用:
講主存中的源操作數減去目的操作數,然后設置標志位,進位比較兩個操作數之間的關系
簡而言之:
意思就是 源內存中的數(可以理解為數,也可能是字符串的ASCII碼) 減去 目的內存中的數,根據結果設置標志位
比如 源內存 的數字是 1 目的內存中 也是1 那么 1 -1 就為0,0是結果,根據結果設置一下標志位 則ZF = 1,也就是源和目的相等
C語言的請看: 相當于memcmp(內存比較) 不懂C語言的濾過
也有兩個比較,分別是字比較,還有字節比較
字節比較: CMPSB DS:[SI]-ES:[DI] 根據方向的標志自增或者自減1 SI<-SI±1,DI<-DI±1
字比較: CMPSB DS:[SI]-ES:[DI] 根據方向的標志自增或者自減2SI<-SI±2,DI<-DI±2
使用例子,字節比較
看下反匯編代碼,然后看下標志位
結果相當,則ZF位為1,如果hello 五個字節都要比較,則來五次即可. (下面還有重復前綴指令,暫時是來五次)
具體的字比較,自己測試便知道
8.串操作指令,串掃描SCAS(Scan String)
作用:
將AL/AX減去目的操作數,以便設置標志,進位比較AL/AX與操作數的關系
簡而言之:
就是你要搜索的字節,放到AL,或者AX中,然后會和DI去比較,然后根據結果設置標志
C語言的請看: 在C語言中,這個相當于 memchr命令
SCASB AL-ES:[DI] 根據方向標志自增或者自減1 DI<-±1
SCASW AX-ES:[DI] 根據方向標志自增或者自減2 DI<-±2
使用例子:
現在是68 - 去內存中DI中的值,也是68
設置標志位,AL中寄存器的值減去DI中的值,根據結果設置標志位,因為68-68結果就是0,所以對應的零標志位置位了
有可能68-69,就是負數了,所以CF位會置位
二丶重復前綴指令(repeat)
1.什么是重復前綴指令?
簡單理解為就是為串操作單獨提供的循環指令,比如我們上面要用MOVS串操作指令的時候,把源寄存器中的值,拷貝到目的寄存器中,假設我們有個HELLO 我們要使用五次 MOVSB命令才能拷貝過去
現在提供了一個為串操作的循環
重復前綴分為兩類,3條指令
1.配合使用,MOVS,STOS,LODS的時候,使用指令REP前綴,不影響標志
2.配合使用 CMPS,SCAS,指令,使用REPZ和REPNZ前綴
然后重復次數放到cx寄存器中
例如
mov cx,3 rep movsb
代表我要重復三次,movsb的指令,注意,根據方向標志,每次自增或者自減1,因為你使用的movsb
REP指令的作用就是 當CX ≠ 0的時候,繼續傳送
REPZ,和REPNZ解析
REPZ:
1.每次執行串指令,則CX-1
2.判斷零標志位(ZF)是否為零 (也就是不想等)
3.如果CX == 0,或者 ZF == 0 (不想等)則重復執行結束
注意可以簡單理解為, cx !=0 并且 zf == 1 的時候繼續循環
REPNZ:
1.每次執行串指令,則CX-1
2.判斷零標志位(ZF)是否為1 (也就是想等)
3.如果CX == 0,或者 ZF ==1 (想等)則重復執行結束
REPNZ/REPNE的前綴,可以簡單理解為 cx != 0 && zf ==0 的時候繼續
使用就很簡單了,上次我們要拷貝的時候必須給五次,這次直接給CX一個值,然后利用前綴指令即可.
三丶控制轉移指令
控制轉移指令,用于實現分支,循環,過程等程序的接口,是僅次于傳送指令的常用指令
一般來說控制轉移指令都是修改IP的偏移或者CS段寄存器的值,讓代碼跳轉(壞處: 斷CPU的流水線)實現
程序的執行順序的改變
①丶無條件轉移指令
無條件轉移指令,就是說你給一個偏移,可以無條件的跳轉到其地放執行
JMP指令(無條件轉移指令)
JMP指令有2個種類,4個類型
1.段內轉移
2.段間轉移
段內轉移:
段內轉移,就是在一個段中的跳轉
又分為短轉移,和近轉移
短轉移(short): 短轉移就是一次只能跳一個字節的大小,也就是 ±127
近轉移(near): 近轉移則是能跳轉 -32767 -> 327678大小
例子:
JMP SHORT 地址/標號
跳轉到地址或者標號的地方
近轉移
對于近轉移來說,機器碼是一個字節,E9是操作碼,而0100則是偏移,就是說你跳轉的偏移的大小是多少
段間轉移
段間轉移,則是去另一個段去跳轉
JMP FAR PTR 地址,標號
例子:
對于段間轉移,則是 段地址:偏移 的形式去轉移的,CS的值會修改為段地址,IP會修改為偏移
注意二進制機器碼,也是這樣的,這個可以自己修改的,因為讓代碼JMP到自己的代碼,然后在JMP回去,就實現了HOOK指令
JMP有兩種尋址指令
直接尋址方式
JMP AX
地址放在寄存器當中
間接尋址方式
JMP word ptr [BX] ;需要指明一下
總結
短轉移: 使用 short 關鍵字 例如 jmp short 標號/地址偏移
近轉移: 使用 near ptr 例如 jmp near ptr 標號/地址偏移
遠轉移: 使用 far ptr 例如 jmp far ptr 標號/地址偏移
然后近轉移和短轉移,可以直接使用jmp,在編譯器中,會自動選擇相應的方式去轉移
四丶條件轉移
上面說的都是強制轉移,現在我們需要使用條件轉移指令,比如根據標志位去轉移
JCC (JCC是一個比喻,并沒有這條命令,可以吧CC看做任何條件)
JCC 標號
CC條件成立則跳轉到標號,否則程序繼續順序執行下一條指令
操作數標號,使用短轉移,成為相對尋址方式
其中CC是一張表組成
看到這張表很難記,有個小竅門
1. z zero(零的意思)/E (equal)
如果為z則是位零的意思,為e則是相等的意思
比如
jz/je 等于零,或者相等,其中判斷的是ZF位
N表示取反的意思
比如
JS SF = 1 表示符號為負
JNS 不看也知道SF = 0 符號位正
其中每個標志位都有一個 判斷是否相等或者不想等
比如 CF位
jC 那么代表CF =1 jNC 那么表示CF = 0
對于上面還不夠,因為我們還要判斷是否 大于,小于 高于,低于 (高于,低于 是用于無符號的判斷,大于小于則是用于符號的判斷)
G 有符號的 大于判斷
L 有符號的小于判斷
A 無符號的高于判斷
B 無符號的低于判斷
比如,我要判斷CF位小于0 JB
如果是CF大于零,則 JNB (不低于) JAE (A是高于 高于等于)
作業以及資料下載鏈接:鏈接:http://pan.baidu.com/s/1boQijU3 密碼:nr3a
總結
以上是生活随笔為你收集整理的16位汇编第八讲指令第四讲的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Balsamiq Mockups 小技巧
- 下一篇: md发布test-1 md发布test-