關於《彙編語言(王爽)》程序6.3使用16個dw 0的問題

在學習王爽老師《彙編語言》的第6.2節時,在程序6.3代碼中,給出了以下的代碼:oop

 1 assume cs:code
 2 code segment
 3     dw 0123h, 0456h, 0789h, 0abch,  0123h, 0456h, 0789h, 0abch
 4     dw 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0
 5 
 6 start: mov ax,cs
 7     mov ss,ax
 8     mov sp,30h
 9     
10     mov bx,0h
11     mov cx,8
12 s:  push cs:[bx]
13     add bx,2
14     loop s
15 
16     mov bx,0
17     mov cx,8
18 s0: pop cs:[bx]
19     add bx,2
20     loop s0
21 
22     mov ax,4c00h
23     int 21h
24 code ends
25 end start

能夠看到第4行中定義了16個dw 0,也就是16個字型數據(32個字節型),隨後將該32個字節內存空間當作棧來使用。初始棧頂爲30h,結構圖以下:學習

從上圖能夠看到,總共花費了48個字節,48轉換成16進制值爲30H,而內存地址從0開始計數,所以這2個dw的內存起止地址爲0~2F,上面的代碼將第二個dw段視做棧空間,初始棧爲空,所以指向棧下面的內存空間,結構以下:spa

因此代碼的第8行將棧偏移地址寄存器SP設置爲30h。調試

這裏有一個問題,第一個dw段只定義了8個字型數據(16個字節),爲了逆序反轉它,應該只須要8個字型大小的棧空間,但實際卻定義了16個字型數據(32個字節),多出來8個字型數據,彷佛是多餘的。更改代碼,將第二個dw段中定義的16個字型數據更改成8個,這樣棧偏移地址寄存器SP就應該設置爲20h,而後調試程序看看,以下:code

首先回憶書本第4章4.9節程序執行過程的跟蹤中的說明,一個程序的加載必定是先找到一段足夠空間的內存,該內存空間的地址段爲SA,偏移地址爲0,所以寄存器CS=SA,寄存器IP=0h。而該內存前面256個字節用來和程序通訊,所以實際的指令段地址爲CS=CS+10h。blog

上機查看加載到內存的代碼指令,能夠看到IP寄存器的值的確爲20h,由於前面32個字節是數據空間,第33個字節纔是真正指令,所以IP指向20h(這是程序源碼中start標誌告訴編譯器的)。另外,也能夠看到第一個壓棧的循環在0B34:002D~0B34:0033處。內存

 

在執行循環壓棧數據以前,先查看代碼指令前20個字節的空間的值,也就是2個dw段中定義的數據。而後一次性執行完第一個循環,使用g命令,令其執行到0B34:0035處開始等待,而後再查看一次前20字節的數據空間,以下:編譯器

從上圖能夠發現一個比較奇怪的地方,那就是棧空間的數據並無改變,第一個dw段的數據沒有壓棧。這不該該,爲何沒有正常工做?再次查看代碼指令,忽然發現代碼指令被改寫了,以下圖:源碼

因爲指令被改寫,那天然上面的程序就沒發正常工做了。那爲何指令的內容會被改變呢?回想書本第3章最後一個問題,也就是實驗2中最後一個提問,爲何棧裏的數據改變了?編譯

最前面的程序使用16個dw字型數據作棧空間時,可以正常工做,而使用8個字型數據時,則出現了問題,這緣由是否是和上面圖中的提問的答案同樣?

相關文章
相關標籤/搜索