当前位置: 首页 > 工具软件 > KDB+ > 使用案例 >

寄存器(3)KDB入门+MIPS汇编及汇编代码详解

慕俊语
2023-12-01


历史:
寄存器(1)寄存器概念,x86寄存器种类说明及汇编代码详解
https://blog.csdn.net/lqy971966/article/details/106780755

1. KDB 介绍及进入退出命令

1.1 KDB 介绍

kdb: build_in kernel debugger 内核调试工具,可以查看内存内容,寄存器信息,跟踪调用栈。
kdb 同GDB一样用于调试程序,区别就是gdb调试的是用户态,kdb调试的是内核态。仅此而已。

kdb 提供丰富的命令实现运行控制、内存操纵、寄存器操纵、断点设置、堆栈跟踪等许多功能,总共有33条命令

1.2 进入KDB及退出KDB

  1. 进入 kdb
    echo 1 > /proc/sys/kernel/kdb 或者 sysctl kernel.kdb=1
    按下:ESC按键
    然后依次按下大写K,D,B三个字母即可
  2. 退出kdb
    删除所有断点,命令:bc *
    然后 go 出去,命令:go

2. KDB 调试

2.1 断点类

kdb提供强大的断点功能,包括设置断点、清除断点、激活断点、使断点失效,kdb也可以设置硬件断点。
断点指令包括bp、bl、bpa、bph、bpha、bc、be和bd。

bp:设置断点
bl:查看当前设置的断点
bc:1 清除断点1
  清除标号为 1 的断点。
bc * 清除所有断点
ss 单步跟踪
go:继续程序执行
  该命令使内核继续执行,直到遇到一个断点才停止。
	如果没有设置断点,该命令将离开kdb调试器,系统回到正常运行状态。

2.2 内存操作类 md

md:显示内存内容

2.3 堆栈跟踪类

该类指令实现对堆栈的跟踪,包括bt、btp和bta三条命令。

bt:显示调用堆栈
  如果不指定参数,它根据当前寄存器的内容显示堆栈

btp:显示进程的堆栈
  格式:btp <pid>
  显示由pid指定的进程的堆栈。

bta:显示所有进程的堆栈
   格式:bta

2.4 寄存器类 rd

寄存器类命令包括对寄存器内容进行显示和修改的rd和rm指令,以及异常帧显示指令ef。

rd :显示寄存器内容
	如果不带任何参数,rd显示所有进入kdb调试器时该点所设置的所有通用寄存器的值。

2.5 其他

id:指令反汇编
	格式:id <vaddr>

从vaddr开始的地址反汇编指令。

3. MIPS 汇编

3.1 mips 寄存器

MIPS有32个通用寄存器($0-$31),各寄存器的功能及汇编程序中使用约定如下:

REGISTER	NAME	USAGE
$0			$zero	永远返回0,常量0(constant value 0)
$1			$at		保留给汇编器(Reserved for assembler)
$2-$3		$v0-$v1	函数调用返回值(values for results and expression evaluation)
$4-$7		$a0-$a3	函数调用的前四个参数(arguments)
$8-$15		$t0-$t7	临时寄存器(或随便用的),可能保存参数,参数5,参数6 ……
$16-$23		$s0-$s7	保存的(或如果用,需要SAVE/RESTORE的)(saved)
$24-$25		$t8-$t9	暂时的(或随便用的),同($t0-$t7)
$26-$27		$k0,$k1	为异常处理程序保留,至少要预留一个 
$28			$gp		全局指针(Global Pointer)
$29			$sp		堆栈指针(Stack Pointer)
$30			$fp		帧指针(Frame Pointer)
$31			$ra		返回地址(return address)

常用的寄存器: v0-v1,a0-$a3,gp

4. 例子参考:

4.1 查看参数 a0-$a3,函数调用的前四个参数(arguments)

a0-$a3 函数调用的前四个参数(arguments)
t 0 − t0- t0t7 保存参数5,参数6 ……

4.1.1 例子1 查看普通入参

[4]kdb>rd	//rd :显示寄存器内容
zero = 0x00000000    at = 0x00000000
v0 = 0xffffffffc1d3a700    v1 = 0x00000006          
a0 = 0x00000006    a1 = 0x00000002                        
a2 = 0xa800000748bfc318    a3 = 0x00000003
……
……
可以查看入参值依次是: 6,2 ,一个指针,3

4.1.2 例子2 查看结构体指针入参

[12]kdb> rd                                                            
zero = 0x00000000    at = 0x00000008                                  
v0 = 0xffffffffc1dad5d0    v1 = 0x00000002                          
a0 = 0xa8000005d9725248    a1 = 0xa8000005da8e0000                  
a2 = 0x00000075    a3 = 0x000063de                                  
……									
cause = 0x00800024 badva = 0xa8000006d99a01e0                          
[12]kdb> md 0xa8000005d9725248   	//md:显示内存内容                                      
0xa8000005d9725248 a8000005da4cd700 a8000005d97f6780   .....L........g.
0xa8000005d9725258 000002a400000000 0000000000000000   ................
0xa8000005d9725268 0000000000000000 0000000000000000   ................
0xa8000005d9725278 0000000000000000 a8000005d9723b10   .............r;.
0xa8000005d9725288 a8000005d9723a10 0000000000000000   .....r:.........
0xa8000005d9725298 0000000000000000 0000000000000000   ................
0xa8000005d97252a8 00000c9c00000000 0000000000000001   ................
0xa8000005d97252b8 6b6b6b6b6b6b6ba5 cccccccccccccccc   kkkkkkk.........
[12]kdb> md a8000005da4cd700                                           
0xa8000005da4cd700 0000000000000000 016b6b6b00000008   .........kkk....
0xa8000005da4cd710 000010036b6b6b6b 6b6b6b6b6b6b6ba5   ....kkkkkkkkkkk. 

入参是个指针, 0xa8000005d9725248
其参数类型:
typedef struct test
{
    //其他
	char c1;	//016b6b6b  6b6b6b是四字节对齐
	int  i1;	//8
	int  i2;	//4099 0x1003
}

4.2 查看返回值 ra -> v0

[37]kdb> go                                                               
Instruction(i) breakpoint #1 at 0xffffffffc1d3bdb0 (adjusted) cpu 37      
0xffffffffc1d3bdb0 xxxxxx_yyyyy:         daddiu      sp,sp,-48            
47 out of 48 cpus in kdb, waiting for the rest, timeout in 10 second(s) 
.All cpus are now in kdb                                                  
																		
Entering kdb (current=0xa8000007fab35358, pid 581) on processor 37 due to Breakpoint @ 0xffffffffc1d3bdb0  
[37]kdb> rd
zero = 0x00000000    at = 0x00000000           
v0 = 0xffffffffc1d3bdb0    v1 = 0x00000006   
a0 = 0x00000006    a1 = 0x00000002           
a2 = 0xa80000074883c318    a3 = 0x00000003   
t0 = 0xa8000005d4a6de70    t1 = 0x00000026   
t2 = 0x00000000    t3 = 0x0000005a           
											
s8 = 0x00000000    ra = 0xffffffffc1ff2f7c   
hi = 0x00000000    lo = 0x00000001           
pc = 0xffffffffc1d3bdb0    sr = 0x14109ce3   
cause = 0x00800024 badva = 0xffffffff801055dc   
[37]kdb> bp 0xffffffffc1ff2f7c      //断住 ra 返回值             
Instruction(i) BP #2 at 0xffffffffc1ff2f7c ([system]xxxxxx_yyyyy2+0x13c) globally       addr at ffffffffc1ff2f7c, hardtype=
0, forcehw=0, installed=0, hard=ffffffff8078c410                           
																		
[37]kdb> go   //走到返回值 ra 处                                      
Instruction(i) breakpoint #2 at 0xffffffffc1ff2f7c (adjusted) cpu 37       
0xffffffffc1ff2f7c xxxxxx_yyyyy2 <+316>:   ld   v0,120(sp)      // 返回值写入v0 寄存器中           
44 out of 48 cpus in kdb, waiting for the rest, timeout in 10 second(s)  
.All cpus are now in kdb                                                   
																		
Entering kdb (current=0xa8000007fab35358, pid 581) on processor 37 due to Breakpoint @ 0xffffffffc1ff2f7c  
[37]kdb> rd v0    //打印返回值的值 0 
v0 = 0x00000000

4.3 查看函数的出参 ra -> a0-a3/t0-t7

要看出参,先要能够断住函数执行结束的地方,其中,ra寄存器(返回地址(return address))中保存的是函数结束后返回上层调用函数的第一条指令。
我们断住这条指令,即可查看相关出参。

查看出参同 4.2 查看返回值 ra -> v0 一样,先断住 ra寄存器 go到ra,然后依次打印a0-a03 t0-t7 看哪个出参即可。

参考:

https://wenku.baidu.com/view/5ed2d89d7dd184254b35eefdc8d376eeafaa1709.html
https://blog.csdn.net/oyangyufu/article/details/6245931
https://blog.csdn.net/flyingqr/article/details/7073088

 类似资料: