文章其實很簡單,在這裡只是想給大家一個提醒。讓大家回顧一下曾經的知識而已,大學的知識,現在你還記得麼?
另外,善意提醒下博客園團隊,雖然我理解商業重要性,但是我個人還是希望把培訓學校的廣告撤下博客園首頁的廣告行列中,我相信博客園是一個純潔的技術博客,大家對博客園都非常信任,我們不希望讓太多的初學者受到這個影響,個人意見而已。
我剛才做一個小軟件的破解,一直被堆棧的操作弄得昏昏沉沉,在這裡寫一下也算是加深一下自己的印象,做個總結,也希望能夠提醒到大家。
步入正題,說說匯編中的棧操作。
首先,我們先來了解一下匯編中,與棧有關的概念。
1. ss: 堆棧段 stack segment
2. sp: 棧指針 stack point
3. pop: 出棧
4. push: 壓棧
相信各位對這些都很清楚不過了。這裡,我從一道很簡單的題把這個問題說清楚:
用push指令(pop指令)把 a 段中的前 8 個字型數據順序存儲到 b 段中。
讓我們先寫最簡單的程序框架:
1assume cs:codeseg
2
3 a segment
4 dw 1,2,3,4,5,6,7,8,9,0aH,0bH,0cH,0dH,0eH,0fH
5 a ends
6
7 b segment
8 dw 0,0,0,0,0,0,0,0
9 b ends
10
11 codeseg segment
12 start:
13 ---------------------------------
14
15 ---------------------------------
16
17 codeseg ends
18
19end start
20
我們需要做的是補充start內部的內容。
首先我們要搞清一些基本的東西:
1. 在壓棧時發生了什麼:首先把棧指針sp - 1 , 然後放入高位數據,然後sp – 1, 然後放入低位數據。 簡單了說,也就是先把sp-2,然後取出數據
2. 在出棧時發生了什麼:首先取出第一個字節的數據,即低位數據,然後sp + 1 , 然後取出高位數據,sp + 1,然後高位數據和低位數據組合。簡單了說,也就是先壓入一個字的數據,然後把sp+2。
那麼好,我們想上面的程序,我們再進一步地寫出來:
1assume cs:codeseg
2 a segment
3 dw 1,2,3,4,5,6,7,8,9,0aH,0bH,0cH,0dH,0eH,0fH
4 a ends
5 b segment
6 dw 0,0,0,0,0,0,0,0
7 b ends
8 codeseg segment
9 start:
10 mov ax,b
11 mov ss,ax
12 mov sp,_______
13 mov ax,a
14 mov es,ax
15 mov bx,_______
16 mov cx,8H
17 loop1:
18 push es:[bx]
19 sub bx,2
20 loop loop1
21 mov ax,4c00H
22 int 21H
23 codeseg ends
24end start
上面的兩處橫線的位置,我們究竟該怎麼去填。
程序的思路很簡單,就是把b段作為一個堆棧段,然後把其他的值壓入。
那麼就讓我們考慮下,sp 這個堆棧段指針究竟該為多少。我們的第一步是要把一個字型數據壓入到第八個word當中,那麼sp應該指向第九個數字所在的地址處,也就是(9-1)*2=16=10H的地址處。因為他壓棧的時候需要的操作首先是把10H-2=0EH,這個0EH指向的則正是第八個word。
接下來看第二個空,我們要把a段中的第八個 word壓入棧中,這個時候,很簡單,我們這個bx應該是第八個word的地址,也就是(8-1)*2=14=0EH。
為什麼同樣是第八個數,而一個是0EH,一個是10H,區別就是因為棧操作時,是先減,後壓。
這樣,我們補全上面的程序:
1assume cs:codeseg
2 a segment
3 dw 1,2,3,4,5,6,7,8,9,0aH,0bH,0cH,0dH,0eH,0fH
4 a ends
5
6 b segment
7 dw 0,0,0,0,0,0,0,0
8 b ends
9
10 codeseg segment
11
12 start:
13 mov ax,b
14 mov ss,ax
15 mov sp,10H
16
17 mov ax,a
18 mov es,ax
19 mov bx,000EH
20 mov cx,8H
21
22 loop1:
23 push es:[bx]
24 sub bx,2
25 loop loop1
26
27 mov ax,4c00H
28 int 21H
29
30 codeseg ends
31end start
測試結果如下:
對於pop操作,依然是同樣的道理。大家感興趣也可以自己試一下。