[045][x86匯編語(yǔ)言]第十五章 習(xí)題1 Bochs完整調(diào)試過程:查看edx寄存器的內(nèi)容、計(jì)算標(biāo)號(hào)mss_type真實(shí)內(nèi)存物理地址

第十五章 習(xí)題解析(以及完整源碼)

http://www.itdecent.cn/p/f19f9236b41f

準(zhǔn)備文件 .lst文件

  • .lst文件根據(jù)同名.asm文件由配書工具nasmide.exe生成
c13_mbr.lst
ex15-1_core.lst
ex15-1_A.lst
ex15-1_B.lst

Bochs 調(diào)試命令(以及配置方法)

配置方法見 http://www.itdecent.cn/p/e8eea9f2ceb5

  • s : 單步執(zhí)行
  • b : 斷點(diǎn)設(shè)置
  • c : 繼續(xù)執(zhí)行
  • r : 查看寄存器
  • sreg : 查看段寄存器
  • xp : 查看內(nèi)存

Bochs 完整調(diào)試過程

  • 調(diào)試過程:加載程序mbr內(nèi)核程序core用戶程序 user(任務(wù)Task-A Mss-1)內(nèi)核程序core;
  • <bochs:n> XXXXXXXX 處輸入 bochs指令 ;
<bochs:1> s
<bochs:2> b 0x7c00
<bochs:3> c
---- 進(jìn)入 mbr -----

<bochs:4> b 0x7d38
<bochs:5> c

---- 跳轉(zhuǎn)到 mbr 最后一條指令 ----------------------
|  c13_mbr.lst
|    136 00000138 FF6F10       jmp far [edi+0x10]  
|    0x7D38 = 0x7c00 + 0x138
--------------------------------------------------

<bochs:6> s
--------- 進(jìn)入core -------------------------------------------------------------
| Bochs
|   (0) [0x0000000415e2] 0038:00000000000003fa (unk. ctxt): mov ecx, 0x00000030
|   讀出內(nèi)核代碼段選擇子是 0x38 
| ex15-1_core.lst
|    946 000003FA B930000000                       mov ecx,core_data_seg_sel          ;令DS指向核心數(shù)據(jù)段 
|    0x03FA正是 .lst文件中 的指令前面的匯編地址
---------------------------------------------------------------------------------

<bochs:7> b 0x0038:0x053c
<bochs:8> c  
----------- (core)來(lái)到習(xí)題 ex15-1 的第一條指令 ----------
|  ex15-1_core.lst
|      1041 0000053C B946000000             mov ecx,0x46
---------------------------------------------------------

<bochs:9> b 0x0038:0x055d
<bochs:10> c
---------(core)即將切換去user Task-A Mss-1 -----------------------------------
|  Bochs
|    (0) [0x000000041745] 0038:000000000000055d (unk. ctxt): callf es:[ecx+20]
|   ex15-1_core.lst
|    1049 0000055D 26FF5914                         call far [es:ecx+0x14]              
--------------------------------------------------------------------------------

<bochs:11> s
---------------- (user)切換到 任務(wù) Task-A Mss-1 ----------------------
|  Bochs
|    (0) [0x0000001004c0] 000f:0000000000000000 (unk. ctxt): mov ax, ds
------------------------------------------------------------------------

<bochs:16> s
----------------- (user)一直單步執(zhí)行 直到 執(zhí)行完 賦值語(yǔ)句 ----------------------
|  Bochs
|    (0) [0x0000001004cb] 000f:000000000000000b (unk. ctxt): mov edx, dword ptr fs:0x00000328 ; 648b1528030000
|  ex15-1_A.lst
|        80 0000000B 648B15[28030000]               mov edx,[fs:mss_type]
------------------------------------------------------------------------------------------------

<bochs:18> r
rdx: 00000000_00000001

<bochs:19> sreg
fs:0x0007, dh=0x0040f310, dl=0x0150032b, valid=3
        Data segment, base=0x00100150, limit=0x0000032b, Read/Write, Accessed

-----------------------------------------------------------------------
| fs 寄存器此時(shí)指向 用戶程序 頭部段
| 讀出 其線性地址  base=0x00100150
| 讀出 段內(nèi)偏移量 見單步調(diào)試結(jié)果里的 fs:0x00000328
| [fs:mss_type] 內(nèi)存真實(shí)物理地址 = 線性地址(0x100150) + 段內(nèi)偏移量(0x328)= 0x100478
------------------------------------------------------------------------

<bochs:21> xp 0x100478
[bochs]:
0x0000000000100478 <bogus+       0>:    0x00000001
------------------- 查看內(nèi)存具體數(shù)值 --------   
|  rdx: 00000000_00000001
|  數(shù)值一致,正確√
--------------------------------------------

<bochs:23> b 0x000f:0x0037
<bochs:24> c
-----------------(user) 執(zhí)行完 user,即將切換回core -------------------------------------------------
|  Bochs
|      (0) [0x0000001004f7] 000f:0000000000000037 (unk. ctxt): callf fs:0x00000128       ; 64ff1d28010000
------------------------------------------------------------------------------------------------------

<bochs:25> s
-----------------(user)調(diào)用門 TerminateProgram -----------------------------------------------
|  ex15-1_core.lst
|    (0) [0x000000040212] 0028:00000000000001fa (unk. ctxt): pushf                     ; 9c
-----------------------------------------------------------------------------------------------

<bochs:26> b 0x0028:0x0230
<bochs:27> c
--------------(user)調(diào)用門 TerminateProgram 的最后一條返回指令 ---------------------------------
|  Bochs
|      (0) [0x000000040248] 0028:0000000000000230 (unk. ctxt): iret                      ; cf
-----------------------------------------------------------------------------------------------

<bochs:28> s
----------------(core) 回到內(nèi)核程序 ----------------------------------------------------------------
|  Bochs
|    (0) [0x000000041749] 0038:0000000000000561 (unk. ctxt): mov ebx, 0x00000f72       ; bb720f0000
|  ex15-1_core.lst
|       1052 00000561 BB[720F0000]                  mov ebx,prgman_msg4
|  接下來(lái)就是 任務(wù) Task-B Mss-1 相關(guān)
|  想要查看edx寄存器的內(nèi)容 以及 內(nèi)存的內(nèi)容
|  重復(fù) <bochs:9> 開始的指令,根據(jù)對(duì)應(yīng)的.LST文件,將段內(nèi)偏移進(jìn)行替換即可
----------------------------------------------------------------------------------------------------

Bochs快速調(diào)試過程

  • 任務(wù) Task-B Mss-1
<bochs:1> s
<bochs:2> b 0x7c00
<bochs:3> c

---- 進(jìn)入 mbr -----

<bochs:4> b 0x7d38
<bochs:5> c
<bochs:6> s

<bochs:7> b 0x0038:0x056D
<bochs:8> c

(0) [0x000000041755] 0038:000000000000056d (unk. ctxt): mov ecx, 0x00000046

<bochs:9> b 0x0038:0x058E
<bochs:10> c
(0) [0x000000041776] 0038:000000000000058e (unk. ctxt): callf es:[ecx+20]

-----------------------------------------------------------------
| 因?yàn)楹芮宄?,?nèi)核代碼段選擇子是 0x0038
| 段內(nèi)偏移量只要查 .lst 文件,找匯編地址填寫上去就可以了
-------------------------------------------------------------------

<bochs:11> s
(0) [0x000000104a10] 000f:0000000000000000 (unk. ctxt): mov ax, ds
---------- 進(jìn)入了 user Task-B Mss-1 ---------------

<bochs:15> s
(0) [0x000000104a1b] 000f:000000000000000b (unk. ctxt): mov edx, dword ptr fs:0x00000328 ; 648b1528030000

<bochs:17> r
rdx: 00000000_00000001 

<bochs:18> sreg
fs:0x0007, dh=0x0040f310, dl=0x46a0032b, valid=3
        Data segment, base=0x001046a0, limit=0x0000032b, Read/Write, Accessed

------------ 計(jì)算真實(shí)內(nèi)存地址 ---------
| fs:0x00000328
| base=0x001046a0
| 0x001046a0+ 0x328 = 1049C8
----------------------------------------------

<bochs:19> xp 0x1049c8
[bochs]:
0x00000000001049c8 <bogus+       0>:    0x00000001

關(guān)于調(diào)試過程

設(shè)置斷點(diǎn)

設(shè)置斷點(diǎn).png
  • 知道段選擇子(Bochs讀出),知道匯編地址(查看.lst文件),就可以精確地設(shè)置斷點(diǎn),比如在內(nèi)核代碼段執(zhí)行的時(shí)候,段選擇子是0x0038,那么斷點(diǎn)肯定是0x0038:NNNN,由于任務(wù)切換返回的時(shí)候要通過調(diào)用門,走到內(nèi)核公用例程段公用例程段的選擇子是0x0028,處理器就是根據(jù)這些段選擇子是去GDT里查找段描述符的。

執(zhí)行流程的基本判斷

---------------------------- ex15-1_A.lst ----------------------------
    77                                  ;-------------------------------------------------------------
    78                                  ; ex15-1    
    79                                  ;-------------------------------------------------------------   
    80 0000000B 648B15[28030000]                mov edx,[fs:mss_type]
    81                                  
    82 00000012 81FA01000000                    cmp edx,1
    83 00000018 7511                            jne .mss2
    84 0000001A BB[00000000]                    mov ebx,mss_1
    85 0000001F 64FF1D[28000000]                call far [fs:PrintString]
    86 00000026 E90C000000                      jmp .mssend
    87                                      .mss2:
    88 0000002B BB[21000000]                    mov ebx,mss_2
    89 00000030 64FF1D[28000000]                call far [fs:PrintString]
    90                                      .mssend:
    91                                  ;---------------------------------------------------------------        
    92                                          
    93                                       
    94 00000037 64FF1D[28010000]                 
  • 舉例說(shuō)明:當(dāng)執(zhí)行 Task-A Mss-1(任務(wù)A 顯示消息1)的切換任務(wù)時(shí),根據(jù)代碼的條件判斷,可以知道代碼的正確流程走向就是執(zhí)行這條跳轉(zhuǎn)86 00000026 E90C000000 jmp .mssend,因此,調(diào)試設(shè)置斷點(diǎn)的時(shí)候,不能設(shè)置斷點(diǎn)到.mss2 后面的 88 0000002B BB[21000000] mov ebx,mss_2,任務(wù)A的消息1的切換過程走不到這里的,然而,此時(shí),在bochs里面,會(huì)看到無(wú)論哪次切換到用戶程序,顯示的段選擇子都是0x000F,因此如果貿(mào)然用了b 0x 000F:0000002B(企圖進(jìn)入.mss2標(biāo)號(hào)后面),那么bochs就會(huì)走到這一步(它會(huì)走到這一步的),因?yàn)樵谌康拇a流程里,的確是有一次可以走到這里,那就是再次切換任務(wù)A顯示消息2的時(shí)候;全部的代碼流程是A1 B1 A2 B2,這樣就是直接跳到了A2,在bochs的虛擬機(jī)窗口可以看到A1 B1的輸出驗(yàn)證這一點(diǎn)。

  • 雖然fs看上去都是0x000F,但是本質(zhì)上不同,通過sreg查看段寄存器,可以看到base的數(shù)據(jù)都是不同的!這恰恰說(shuō)明了,A1 B1 A2 B2 其實(shí)就是4個(gè)完全不同的任務(wù),它們在內(nèi)存的不同位置存放著,它們彼此毫無(wú)關(guān)系。

詳細(xì)圖解(根據(jù)文件名對(duì)應(yīng)具體步驟)

[core]1.進(jìn)入內(nèi)核程序 使用斷點(diǎn) 跳轉(zhuǎn)到顯示完CPU信息處.png
[core]2、跳轉(zhuǎn)到習(xí)題1 解答代碼開始處.png
[user]1、切換到任務(wù)A 顯示message1.png
[user]2、讀出用戶程序代碼段選擇子.png
[user]3、查看控制消息顯示參數(shù)的值是否正確傳遞.png
[user]4、調(diào)用門 執(zhí)行內(nèi)核程序 公用例程段的子程序.png
[user]5、第一次切換到任務(wù)A 顯示消息1 并返回.png
真實(shí)內(nèi)存地址.png
如何計(jì)算 mss_type 所在的真實(shí)內(nèi)存物理地址.png
任務(wù)A 消息2.png
任務(wù)B 消息2.png
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容