實驗 5 編寫、調試具備多個段的程序

1、實驗目的

1. 理解和掌握將數據、代碼、棧放入不一樣段的程序的編寫和調試編程

2. 理解具備多個段的彙編源程序對應的目標程序執行時,內存分配方式框架

 

2、實驗準備

1. 結合第 6 章教材和課件,複習第 6 章內容spa

2.  複習第 3 章「棧」的知識debug

 

3、實驗內容

實驗任務(1)3d

下載課程公郵中的程序框架放入,masm.exe,link.exe同文件夾下,用DS BOX掛載到masm文件夾後調試

使用以前寫好的process.bat文件簡化編譯,鏈接,執行操做。code

順利執行,下面對ex5_1.exe debug。blog

 

使用r命令查看各寄存器的值,下面咱們要精確反彙編程序段,首先經過r命令能夠看出cx=0042,內存

即這段程序所佔的字節數是42h,但這還包括數據段和棧段,數據段有8個數據,16個字節,即io

10h,棧段也是16個字節,即10h。因此代碼段長度爲42-20=22h,CS:IP = 076C:0000,因此若要精確反彙編

,應該是u 0000 0021(注:代碼段,棧段,數據段均是從0開始的)。成功反彙編代碼段。

題目要求的是程序返回前,即 mov ax,4c00   int 21前,根據反彙編結果可知,因執行到CS:001d前,使用

g命令達到這一效果。

已經能夠看出CPU執行程序,程序返回前,cs=076c,ss=076b,ds=076a.

接下來須要查看數據段,已知數據段長16個字節,使用d命令查看內存中的數據 d 0 f(注:代碼段,棧段,數據段均是從0開始的)

能夠看出,程序返回前的數據段並無改變(讀數據時注意是小端法存儲的)。

使用g命令執行完程序,程序加載後,能夠看出DS = CS-2,SS=CS-1;

根據實驗結果完成了書中填空。

實驗任務(2)

前期步驟同(1)

同實驗(1),首先經過r命令能夠看出cx=0042,即這段程序所佔的字節數是42h,但這還包括數據段和棧段,數據段有2個數據,4個字節,棧段也是2個字節。

因此代碼段長度爲42-8=34h,CS:IP = 076C:0000,因此若要精確反彙編

,應該是u 0000 0033(注:代碼段,棧段,數據段均是從0開始的)。但這裏我卻並無作到成功反彙編,顯然咱們所給反彙編範圍大了

經過查看源代碼,給出猜想,雖然棧段和數據段都只給出了4個字節,但從第13行代碼看出

,這裏設sp = 16,棧頂設爲了16,也就是說這裏的棧仍然是16個字節的,儘管沒有填滿,因此狀況應該和

實驗(1)是同樣的,固然這只是個人猜想

精確反彙編的結果與實驗(1)同樣

題目要求的是程序返回前,即 mov ax,4c00   int 21前,根據反彙編結果可知,因執行到CS:001d前,使用

g命令達到這一效果。

已經能夠看出CPU執行程序,程序返回前,cs=076c,ss=076b,ds=076a.

接下來須要查看數據段,已知數據段長4個字節,使用d命令查看內存中的數據 d 0 3(注:代碼段,棧段,數據段均是從0開始的)

能夠看出,程序返回前的數據段並無改變(讀數據時注意是小端法存儲的)。

使用g命令執行完程序,程序加載後,能夠看出DS = CS-2,SS=CS-1;

這裏的狀況和實驗(1)是同樣的

考慮對於以下定義的段:

name segment

...

name ends

經過查閱資料得知

若是段中數據佔N個字節,則程序加載後,該段實際佔有的空間爲 [(N+15)/16]*16。

數據段都是以16個字節對齊,不足16字節按16字節算,這也解釋了對於實驗任務(2)個人

疑問。

根據實驗結果完成書中填空

實驗任務(3)

與實驗任務(1)(2)相同,前面的步驟在這裏就省略截圖分析了,直接從debug後開始

這裏的精確反彙編又出現了問題,根據以前的實驗總結,應該是CX = 44-10-10=24h,

因此應該是 u 0 23進行精確反彙編,但這裏卻仍是應該 u 0 21。緣由不得而知。

修改後精確反彙編

已經能夠看出CPU執行程序,程序返回前,cs=076a,ss=076e,ds=076d.

接下來須要查看數據段,已知數據段長4個字節,使用d命令查看內存中的數據 d 0 3(注:代碼段,棧段,數據段均是從0開始的)

能夠看出,程序返回前的數據段並無改變(讀數據時注意是小端法存儲的)。

使用g命令執行完程序,程序加載後,能夠看出DS = CS+3,SS=CS+4;

根據實驗結果完成書中填空

實驗任務(4)

若是將(1),(2),(3)題中的最後一條僞指令「end start」改成「end」(也就是說,不指明程序的入口個),則哪一個程序仍然能夠正確執行?請說明緣由。

對三個程序內容進行修改編譯鏈接執行後

對第一個程序的反彙編結果,能夠發現該程序已經沒有辦法正確執行

程序2也是沒法正確執行

程序3能夠正確執行

由於若是沒有end start就會默認以IP=0開始執行,而不是從start開始執行。

而實驗內容(3)的data和stack都在code以後,因此IP原本就爲0,能夠正確執行。

 

實驗任務(5)

(1) 彙編程序源代碼

補全代碼以下:

分析:編寫code代碼,將a段b段中的數據依次相加,將結果存在c段中。

bx用於偏移量,初始置顯然爲0,dx爲求和寄存器初始值也是0,cx用於設置循環次數,這裏有a,b中均有8個字

,因此循環次數也就是8次。

循環體部分:每次將a段中和b段中內容依次加到寄存器dx中,最後將結果存到c段中。

這裏須要注意,循環體開頭部分每次都要將用於求和的寄存器bx置爲0,不然上次的結果會接着累加。

偏移量bx每次增長一次,大致步驟就是這樣,具體細節在這裏就不作過多的闡述。

(2)  在 debug 中調試程序截圖,截圖中包括以下信息:

① 在實現數據相加前,邏輯段 c 的 8 個字節

進入debug,而後查看寄存器,精確反彙編(CX-10h-10h-10h=29h),u 0 28

根據精確反彙編結果,執行到循環體外,使用d命令查看數據段內容,發現並無作到預期,

但查看棧段內容時,發現第二行到第四行顯示的內存符合預期,緣由不得而知。

② 執行完實現加運算的代碼後,邏輯段 c 的 8 個字節

使用g命令執行完成後,發現用d命令查看數據段內存內容仍然不符合預期,但棧段內存內容

符合,第四行確實是前兩行相加的結果。

根據①和②的調試,證明了程序確實正確的實現數據相加。

 

實驗任務(6)

(1) 彙編程序源代碼

補全代碼以下:

分析:編寫code段中的代碼,用push指令將a段中的前8個字型數據,逆序存儲b段中。

須要逆序存儲,天然的便想到了棧段,這裏須要設一個棧段,須要將b段前8個字數據逆序存儲,

8個字數據即16個字節,棧頂SP = 16 =10h,棧底爲SS = SP+1.

這裏只要設置8次循環,將a段中前8個字型數據push到棧中,即實現了題目要求。

(2)   debug 中調試程序截圖,截圖中包括以下信息:

進入debug,使用r命令進行查看,精確反彙編(CX-20h-10h=1fh)u 0 1e

成功精確反彙編。

① 在 push 操做執行前,查看邏輯段 b 8 個字單元信息截圖

根據反彙編結果,使用g命令執行到push操做前,用d命令查看內存中內容,長度爲a段的

32(20h)個字節加上b段16(10h)個字節,d ds:0 29.

能夠看出b段8個字全是0.

② 執行 push 操做,而後再次查看邏輯段 b 8 個子單元信息截圖

使用g命令執行完成後,用d命令查看,發現b的8個字單元爲a段前8個字節的逆序.

 根據①和②的調試,驗證程序確實正確的實現題目要求。

 

5、總結與體會

 1.經過這次實驗理解和掌握將數據、代碼、棧放入不一樣段的程序的編寫和調試

理解具備多個段的彙編源程序對應的目標程序執行時,內存分配方式。

2.咱們開始逐漸進入到彙編編程中,彙編也並非很枯燥的,在實驗過程當中只有不斷的探索嘗試才能真正

體會彙編的樂趣。

相關文章
相關標籤/搜索