[045][x86汇编语言]第十五章 习题1 Bochs完整调试过程:查看edx寄存器的内容、计算标号mss_type真实内存物理地址

第十五章 习题解析(以及完整源码)

https://www.jianshu.com/p/f19f9236b41f

准备文件 .lst文件

  • .lst文件根据同名.asm文件由配书工具nasmide.exe生成
c13_mbr.lst
ex15-1_core.lst
ex15-1_A.lst
ex15-1_B.lst

Bochs 调试命令(以及配置方法)

配置方法见 https://www.jianshu.com/p/e8eea9f2ceb5

  • s : 单步执行
  • b : 断点设置
  • c : 继续执行
  • r : 查看寄存器
  • sreg : 查看段寄存器
  • xp : 查看内存

Bochs 完整调试过程

  • 调试过程:加载程序mbr内核程序core用户程序 user(任务Task-A Mss-1)内核程序core
  • XXXXXXXX 处输入 bochs指令
 s
 b 0x7c00
 c
---- 进入 mbr -----

 b 0x7d38
 c

---- 跳转到 mbr 最后一条指令 ----------------------
|  c13_mbr.lst
|    136 00000138 FF6F10       jmp far [edi+0x10]  
|    0x7D38 = 0x7c00 + 0x138
--------------------------------------------------

 s
--------- 进入core -------------------------------------------------------------
| Bochs
|   (0) [0x0000000415e2] 0038:00000000000003fa (unk. ctxt): mov ecx, 0x00000030
|   读出内核代码段选择子是 0x38 
| ex15-1_core.lst
|    946 000003FA B930000000                       mov ecx,core_data_seg_sel          ;令DS指向核心数据段 
|    0x03FA正是 .lst文件中 的指令前面的汇编地址
---------------------------------------------------------------------------------

 b 0x0038:0x053c
 c  
----------- (core)来到习题 ex15-1 的第一条指令 ----------
|  ex15-1_core.lst
|      1041 0000053C B946000000             mov ecx,0x46
---------------------------------------------------------

 b 0x0038:0x055d
 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]              
--------------------------------------------------------------------------------

 s
---------------- (user)切换到 任务 Task-A Mss-1 ----------------------
|  Bochs
|    (0) [0x0000001004c0] 000f:0000000000000000 (unk. ctxt): mov ax, ds
------------------------------------------------------------------------

 s
----------------- (user)一直单步执行 直到 执行完 赋值语句 ----------------------
|  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]
------------------------------------------------------------------------------------------------

 r
rdx: 00000000_00000001

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

-----------------------------------------------------------------------
| fs 寄存器此时指向 用户程序 头部段
| 读出 其线性地址  base=0x00100150
| 读出 段内偏移量 见单步调试结果里的 fs:0x00000328
| [fs:mss_type] 内存真实物理地址 = 线性地址(0x100150) + 段内偏移量(0x328)= 0x100478
------------------------------------------------------------------------

 xp 0x100478
[bochs]:
0x0000000000100478 :    0x00000001
------------------- 查看内存具体数值 --------   
|  rdx: 00000000_00000001
|  数值一致,正确√
--------------------------------------------

 b 0x000f:0x0037
 c
-----------------(user) 执行完 user,即将切换回core -------------------------------------------------
|  Bochs
|      (0) [0x0000001004f7] 000f:0000000000000037 (unk. ctxt): callf fs:0x00000128       ; 64ff1d28010000
------------------------------------------------------------------------------------------------------

 s
-----------------(user)调用门 TerminateProgram -----------------------------------------------
|  ex15-1_core.lst
|    (0) [0x000000040212] 0028:00000000000001fa (unk. ctxt): pushf                     ; 9c
-----------------------------------------------------------------------------------------------

 b 0x0028:0x0230
 c
--------------(user)调用门 TerminateProgram 的最后一条返回指令 ---------------------------------
|  Bochs
|      (0) [0x000000040248] 0028:0000000000000230 (unk. ctxt): iret                      ; cf
-----------------------------------------------------------------------------------------------

 s
----------------(core) 回到内核程序 ----------------------------------------------------------------
|  Bochs
|    (0) [0x000000041749] 0038:0000000000000561 (unk. ctxt): mov ebx, 0x00000f72       ; bb720f0000
|  ex15-1_core.lst
|       1052 00000561 BB[720F0000]                  mov ebx,prgman_msg4
|  接下来就是 任务 Task-B Mss-1 相关
|  想要查看edx寄存器的内容 以及 内存的内容
|  重复  开始的指令,根据对应的.LST文件,将段内偏移进行替换即可
----------------------------------------------------------------------------------------------------

Bochs快速调试过程

  • 任务 Task-B Mss-1
 s
 b 0x7c00
 c

---- 进入 mbr -----

 b 0x7d38
 c
 s

 b 0x0038:0x056D
 c

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

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

-----------------------------------------------------------------
| 因为很清楚了,内核代码段选择子是 0x0038
| 段内偏移量只要查 .lst 文件,找汇编地址填写上去就可以了
-------------------------------------------------------------------

 s
(0) [0x000000104a10] 000f:0000000000000000 (unk. ctxt): mov ax, ds
---------- 进入了 user Task-B Mss-1 ---------------

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

 r
rdx: 00000000_00000001 

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

------------ 计算真实内存地址 ---------
| fs:0x00000328
| base=0x001046a0
| 0x001046a0+ 0x328 = 1049C8
----------------------------------------------

 xp 0x1049c8
[bochs]:
0x00000000001049c8 :    0x00000001

关于调试过程

设置断点

[045][x86汇编语言]第十五章 习题1 Bochs完整调试过程:查看edx寄存器的内容、计算标号mss_type真实内存物理地址_第1张图片
设置断点.png
  • 知道段选择子(Bochs读出),知道汇编地址(查看.lst文件),就可以精确地设置断点,比如在内核代码段执行的时候,段选择子是0x0038,那么断点肯定是0x0038:NNNN,由于任务切换返回的时候要通过调用门,走到内核公用例程段公用例程段的选择子是0x0028,处理器就是根据这些段选择子是去GDT里查找段描述符的。

执行流程的基本判断

---------------------------- 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]                 
  • 举例说明:当执行 Task-A Mss-1(任务A 显示消息1)的切换任务时,根据代码的条件判断,可以知道代码的正确流程走向就是执行这条跳转86 00000026 E90C000000 jmp .mssend,因此,调试设置断点的时候,不能设置断点到.mss2 后面的 88 0000002B BB[21000000] mov ebx,mss_2任务A的消息1的切换过程走不到这里的,然而,此时,在bochs里面,会看到无论哪次切换到用户程序,显示的段选择子都是0x000F,因此如果贸然用了b 0x 000F:0000002B(企图进入.mss2标号后面),那么bochs就会走到这一步(它会走到这一步的),因为在全部的代码流程里,的确是有一次可以走到这里,那就是再次切换任务A显示消息2的时候;全部的代码流程是A1 B1 A2 B2,这样就是直接跳到了A2,在bochs的虚拟机窗口可以看到A1 B1的输出验证这一点。

  • 虽然fs看上去都是0x000F,但是本质上不同,通过sreg查看段寄存器,可以看到base的数据都是不同的!这恰恰说明了,A1 B1 A2 B2 其实就是4个完全不同的任务,它们在内存的不同位置存放着,它们彼此毫无关系。

详细图解(根据文件名对应具体步骤)

[045][x86汇编语言]第十五章 习题1 Bochs完整调试过程:查看edx寄存器的内容、计算标号mss_type真实内存物理地址_第2张图片
[core]1.进入内核程序 使用断点 跳转到显示完CPU信息处.png
[045][x86汇编语言]第十五章 习题1 Bochs完整调试过程:查看edx寄存器的内容、计算标号mss_type真实内存物理地址_第3张图片
[core]2、跳转到习题1 解答代码开始处.png
[045][x86汇编语言]第十五章 习题1 Bochs完整调试过程:查看edx寄存器的内容、计算标号mss_type真实内存物理地址_第4张图片
[user]1、切换到任务A 显示message1.png
[045][x86汇编语言]第十五章 习题1 Bochs完整调试过程:查看edx寄存器的内容、计算标号mss_type真实内存物理地址_第5张图片
[user]2、读出用户程序代码段选择子.png
[045][x86汇编语言]第十五章 习题1 Bochs完整调试过程:查看edx寄存器的内容、计算标号mss_type真实内存物理地址_第6张图片
[user]3、查看控制消息显示参数的值是否正确传递.png
[045][x86汇编语言]第十五章 习题1 Bochs完整调试过程:查看edx寄存器的内容、计算标号mss_type真实内存物理地址_第7张图片
[user]4、调用门 执行内核程序 公用例程段的子程序.png
[045][x86汇编语言]第十五章 习题1 Bochs完整调试过程:查看edx寄存器的内容、计算标号mss_type真实内存物理地址_第8张图片
[user]5、第一次切换到任务A 显示消息1 并返回.png
[045][x86汇编语言]第十五章 习题1 Bochs完整调试过程:查看edx寄存器的内容、计算标号mss_type真实内存物理地址_第9张图片
真实内存地址.png
[045][x86汇编语言]第十五章 习题1 Bochs完整调试过程:查看edx寄存器的内容、计算标号mss_type真实内存物理地址_第10张图片
如何计算 mss_type 所在的真实内存物理地址.png
[045][x86汇编语言]第十五章 习题1 Bochs完整调试过程:查看edx寄存器的内容、计算标号mss_type真实内存物理地址_第11张图片
任务A 消息2.png
[045][x86汇编语言]第十五章 习题1 Bochs完整调试过程:查看edx寄存器的内容、计算标号mss_type真实内存物理地址_第12张图片
任务B 消息2.png

你可能感兴趣的:([045][x86汇编语言]第十五章 习题1 Bochs完整调试过程:查看edx寄存器的内容、计算标号mss_type真实内存物理地址)