1. 理解和掌握將數據、代碼、棧放入不一樣段的程序的編寫和調試編程
2. 理解具備多個段的彙編源程序對應的目標程序執行時,內存分配方式框架
1. 結合第 6 章教材和課件,複習第 6 章內容spa
2. 複習第 3 章「棧」的知識debug
實驗任務(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個字節的逆序.
根據①和②的調試,驗證程序確實正確的實現題目要求。
1.經過這次實驗理解和掌握將數據、代碼、棧放入不一樣段的程序的編寫和調試
理解具備多個段的彙編源程序對應的目標程序執行時,內存分配方式。
2.咱們開始逐漸進入到彙編編程中,彙編也並非很枯燥的,在實驗過程當中只有不斷的探索嘗試才能真正
體會彙編的樂趣。