程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> 更多編程語言 >> 匯編語言 >> 說清匯編中的棧操作地址問題

說清匯編中的棧操作地址問題

編輯:匯編語言

文章其實很簡單,在這裡只是想給大家一個提醒。讓大家回顧一下曾經的知識而已,大學的知識,現在你還記得麼?

另外,善意提醒下博客園團隊,雖然我理解商業重要性,但是我個人還是希望把培訓學校的廣告撤下博客園首頁的廣告行列中,我相信博客園是一個純潔的技術博客,大家對博客園都非常信任,我們不希望讓太多的初學者受到這個影響,個人意見而已。

我剛才做一個小軟件的破解,一直被堆棧的操作弄得昏昏沉沉,在這裡寫一下也算是加深一下自己的印象,做個總結,也希望能夠提醒到大家。

步入正題,說說匯編中的棧操作。

首先,我們先來了解一下匯編中,與棧有關的概念。

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操作,依然是同樣的道理。大家感興趣也可以自己試一下。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved