冰楓論壇

 找回密碼
 立即註冊
搜索
查看: 175|回覆: 0
打印 上一主題 下一主題

[心得] 堆疊的應用

[複製鏈接]

13

主題

0

好友

27

積分

新手上路

Rank: 1

UID
460236
帖子
23
主題
13
精華
0
積分
27
楓幣
876
威望
26
存款
0
贊助金額
0
推廣
0
GP
14
閱讀權限
10
性別
保密
在線時間
22 小時
註冊時間
2024-10-12
最後登入
2024-12-24
跳轉到指定樓層
1
發表於 2024-11-22 08:17:36 |只看該作者 |倒序瀏覽
本帖最後由 ikj78i 於 2024-11-22 08:21 編輯

堆疊是記憶體中的一塊區域,程式一開始執行時,系統會保留一塊記憶體給堆疊使用。等所有
初始化工作完成,ESP就指向堆疊某處,此位址及比此位址高的記憶體存有系統保留的資料,
比這個位址低的記憶體空間都是空的。此為指稱為堆疊頂。
x86 CPU利用PUSH指令把資料存入堆疊,它的語法是
  PUSH 來源運算元
  來源運算元可以是暫存器、變數、常數

每當PUSH來源運算元時,ESP會先減少,然後再把來源運算元存入ESP所指的位址。至於減少多
少,要看來源運算元長度。如果是WORD就減少2;如果;是DWORD就減少4。而此時堆疊頂就比原
先少2或少4。像這樣把資料存入堆疊使ESP減少稱為把資料推入堆疊。
而讀取堆疊的資料則用x86指令
  POP 目的運算元
  目的運算元只能是暫存器、變數

當POP目的運算元時,先把ESP所指的堆疊頂資料存入目的運算元,再使ESP增加。增加多少跟
目的運算元的長度有關。這樣的過程稱為彈出資料。
舉例來說,假如有底下三個指令,X、Y、Z都是字組,ESP為106
      堆疊位址 低-->高
指令     ESP 100 102 104 106
PUSH X  106             DDD 尚未執行PUSH X
PUSH Y  104          X  DDD 尚未執行PUSH Y,而PUSH X已執行完畢
PUSH Z  102      Y   X  DDD 尚未執行PUSH Z,而PUSH Y已執行完畢
        102  Z   Y   X  DDD PUSH Z已執行完畢

假如現在要把上面三個堆疊的資料依序彈出,且存於位址300處
指令   ESP 100 102 104 106....300 302 304 306
POP [300] 100  Z   Y   X  DDD                    尚未執行POP [300]
POP [302] 102      Y   X  DDD     Z              尚未執行POP [302],已執行POP [300]
POP [304] 104          X  DDD     Z   Y          尚未執行POP [304],已執行POP [302]
          106             DDD     Z   Y   X      已執行完POP [306]

堆疊有一種很特別的性質,最先推入堆疊的資料,卻是最後才能彈出。上面的例子X是最先推入
堆疊,再彈出後卻是在最高位址。由於堆疊有這種特性,很適合把資料做倒敘排列(就是先後順
序顛倒)
回文詩是中文特有的詩體,正讀與倒讀都有意義,例如底下的例子:
  1. ;底下的PALINDROME.ASM把宋朝李禺兩相思的正文夫思妻,回文後變妻思夫
  2. ;此程式利用堆疊先進後出的特性就能造成回文詩的效果。
  3. .586
  4. .model  flat,stdcall
  5. option  casemap:none
  6. include    c:\masm32\include\windows.inc
  7. include    c:\masm32\include\kernel32.inc
  8. includelib c:\masm32\lib\kernel32.lib
  9. ;*******************************************************************************
  10. .DATA
  11. hOut    DD      ?
  12. dOut    DD      ?
  13. author  DB      "《兩相思》 宋 李禺",0dh,0ah
  14. poem    DB      "枯眼遙望山隔水,往來曾見幾心知。",0dh,0ah
  15.         DB      "壺空怕酌一杯酒,筆下難成和韻詩。",0dh,0ah
  16.         DB      "途路阻人離別久,訊音無雁寄回遲。",0dh,0ah
  17.         DB      "孤燈夜守長寥寂,夫憶妻兮父憶兒。",0dh,0ah
  18. palindromed     DB      0dh,0ah,"回文後:",0dh,0ah
  19. poem_size       EQU     OFFSET palindrome_poem-OFFSET author
  20. poem_text_size  EQU     OFFSET palindromed-OFFSET poem
  21. palindrome_poem DB      poem_text_size+4 DUP (0)
  22. ;*******************************************************************************
  23. .CODE
  24. ;-------------------------------------------------------------------------------

  25. ;-------------------------------------------------------------------------------
  26. main    PROC
  27.         invoke  GetStdHandle,STD_OUTPUT_HANDLE
  28.         mov     hOut,eax
  29.         invoke  WriteConsole,hOut,OFFSET author,poem_size,OFFSET dOut,0
  30.     ;把正文推入堆疊
  31.         lea     edx,poem
  32.         mov     ecx,17*4        ;每列包含標點符號及換行符號共17個字組,有4列
  33. next1:  push    WORD PTR [edx]  ;從peom字串的第一個字組推入堆疊,它在堆疊最高位址
  34.         add     edx,2           ;而後依次把下個字組推入堆疊,存放位址越來越低
  35.         loop    next1
  36.     ;由堆疊中取回(彈出)詩文,存放於palindrome_poem
  37.         mov     ecx,17*4        ;堆疊內已存放17*4個字組
  38.         lea     edx,palindrome_poem ;資料由堆疊彈出後的存放位址
  39. next2:  pop     WORD PTR [edx]      ;彈出一個字組,存放於EDX所指的位址
  40.         add     edx,2               ;每彈出一個堆疊,EDX所指位址往後增加2
  41.         loop    next2
  42.     ;處理每列最後面的標點符號及換行符號,它們必須交換位置
  43.         mov     ecx,3
  44.         lea     edx,palindrome_poem
  45.         add     edx,34
  46. next3:  mov     ax,[edx]
  47.         xchg    ax,[edx+2]
  48.         mov     [edx],ax
  49.         add     edx,34
  50.         loop    next3
  51.     ;處理最後一行的句號
  52.         mov     WORD PTR[edx],043a1h
  53.         invoke  WriteConsole,hOut,OFFSET palindrome_poem+4,poem_text_size,OFFSET dOut,0
  54.         invoke  ExitProcess,0
  55. main    ENDP
  56. ;*******************************************************************************
  57. END     main
複製代碼
依下面步驟組譯、連結並執行:

PA.png (15.02 KB, 下載次數: 0)

李禺兩相思

李禺兩相思

收藏收藏0 推0 噓0


把本文推薦給朋友或其他網站上,每次被點擊增加您在本站積分: 1鑰匙
複製連結並發給好友,以賺取推廣點數
簡單兩步驟,註冊、分享網址,即可獲得獎勵! 一起推廣文章換商品、賺$$
高級模式
B Color Image Link Quote Code Smilies |上傳

廣告刊登意見回饋關於我們管群招募本站規範DMCA隱私權政策

Copyright © 2011-2024 冰楓論壇, All rights reserved

免責聲明:本網站是以即時上載留言的方式運作,本站對所有留言的真實性、完整性及立場等,不負任何法律責任。

而一切留言之言論只代表留言者個人意見,並非本網站之立場,用戶不應信賴內容,並應自行判斷內容之真實性。

小黑屋|手機版|冰楓論壇

GMT+8, 2024-12-26 19:45

回頂部