實驗2 用機器指令和匯編指令編程
1、預備知識:Debug的使用
(1)、D、E、A、U命令的新用法
? 上次實驗中查看指定的記憶體單元的內容的方法是 “-d 段地址:偏移地址”,即直接給出段地址以及偏移地址,但這種操作方式是 Debug 程式提供的一種直觀的操作方式,實際上,Debug 在執行這樣的命令時,也會將段地址先送入段暫存器中,而這個段暫存器不是別人,正是專業儲存資料地址的段暫存器 DS(Data Section) ,難道這也在你的計算中嗎jojo?
? 因此,D 命令也提供了一種符合 CPU 運轉機理的格式:"-d 段暫存器:偏移地址",以段暫存器中的資料為段地址 SA,
-r ds
: 1000
-d ds:0 f ;查看從1000:0000H ~ 1000:000fH的記憶體空間中的內容
-d cs:0 ;查看當前代碼段中的指令代碼
-d ss:0 ;查看當前堆疊段中的內容
E、A、U 指令同理,此處不再贅述,
(2)、消失的指令
是的,你沒有看錯,這個小標題對應的段落不是走近科學的文案,而是今天實驗內容的一部分
讓我們來看下面這段指令:

? 在使用T命令執行 “mov ax,2000” 后,顯示出當前 CPU 暫存器的狀態和下一步要執行的指令:“mov ss,ax”;
? 但是,在使用 T 命令單步執行 “mov ss,ax” 后,我們發現了一個問題: “mov ss,ax” 的下一條指令應該是 “mov sp,10” ,但是現在怎么變成了它的下一條指令 “mov ax,3123”?
? 那么, “mov sp,10” 是已經被執行了嗎?還是說直接被跳過了呢?
? 仔細觀察發現:在程式執行前,sp = ffee,而在程式執行之后,sp 變成了 0010,所以說, “mov sp,10” 已經得到了執行,并且是在執行完 “mov ss,ax” 的時候緊接著執行的,
? 一般情況下,使用 T 命令執行一條指令后,它的下一條指令會停止繼續執行,顯示出當前CPU各個暫存器的狀態以及下一步要執行的指令,但是顯然T命令執行 “mov ss,ax” 的時候沒有做到這一點,并且據實驗表明,對于其他修改堆疊段暫存器(Stack Section)SS的指令如 “mov ss,[0]”、 “pop ss” 等指令時都會發生上述情況,
? 那么,到底是什么導致了這一點呢?請容我賣個關子,在文章的最后揭曉,
2、實驗任務
(1)、使用 Debug ,將下面的程式寫入記憶體,逐條執行,并按要求填空


毫無意外的, “mov sp,0100” 這句代碼又一次被直接執行了,

別忘了,堆疊的儲存方式是從堆疊頂壓入,所以這個push壓堆疊指令存入AX中的十六位資料的時候,高地址單元中存放的實際上是高位資料,也就是說,資料的前后兩位被顛倒了



實驗結果:

(2)、離奇改變的記憶體空間
讓我們來看看這個問題:


讓我們進行分析:
首先,我沒有任何訪問記憶體的動作
其次,我只是把資料在暫存器之間進行了復制操作
但是看記憶體的數值,它確實發生了改變
所以,到底為什么記憶體資料會自己改變呢?
聰明的我當機立斷,抄起一根ddr4記憶體條含到嘴里,結合互聯網上的蛛絲馬跡,我推斷出了答案


根據目前手上的線索,答案可能就是當 Debug 程式使用 T 命令一條一條的執行指令時,可能會先將暫存器中的值先行壓入堆疊中再執行原來的執行一條指令暫停一次的中斷操作,以保證資料的安全,
而當我們更改了堆疊段暫存器SS的值的時候,因為堆疊段的位置改變了,而偏移地址的位置沒有改變,所以Debug默認下一條指令是更改堆疊指標暫存器(Stack Pointer)SP的值,以便確認新的堆疊段位置后才執行中斷指令把暫存器的值壓入堆疊中保存,
結合這個大膽的推斷,我們來看記憶體的值,果然,記憶體中儲存的值與暫存器中的值是一一對應的,
隨后,我們帶著方向到網上尋求正解:

我們的大膽推論終于還是得到了證實,我愿稱之為”走進科學-程式員專欄-萬圣節特別節目——Debug背后的神秘陰影“,總之,這就是學習的精華與魅力所在——大膽胡說,小心求證,希望大家能和我一起在匯編(tutou)的路上越走越遠
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/200344.html
標籤:其他
上一篇:訪問github失敗
