让程序跳转到某绝对地址执行——程序计数器PC(esp和ebp)

第一:跳转PC指针指定的地址处执行程序。

已知:函数int a=2;的地址是0x08000734; int b=4;的地址是0x08000736; int c=6;的地址是0x08000738。
第一步:手动改变R15(PC程序计数器)的值为0x08000736,函数的执行语句会跳到int b=4所在的211行。

第二步:手动改变R15(PC程序计数器)的值为0x08000738,函数的执行语句会跳到int c=6所在的212行。

如下图所示

之所以记录这个是因为今天同事问了我一个问题,她仿真的时候,可以知道是哪个地址执行的程序挂掉了,那如何在kei中快速定位到这个位置呢?问题类似和这个人问的一样:https://www.amobbs.com/thread-5613466-1-2.html?_dsign=2688ccd3 

现在在跟一个NMI fault ,已经定位了它出错附近的代码地址为 0x200027F1 ,以前用IAR的时候,在汇编窗口有个输入窗口,只要把这个地址输入的那个窗口然后回车就会跳转到对应的的汇编代码处,
然后根据汇编代码对应的C代码来查找出错的原因。现在用keil MDK 了它的汇编窗口好像没有那个能输入地址的窗口。请问大家是如何定位的?怎样找到地址0x200027F1对应的汇编代码。

然后我觉得这种在keil中改变PC程序计数器似乎也可以定位到出错的地址的位置。

第二:关于keil的复位按钮的作用。

keil的复位是仿真器复位后,程序计数器PC指针将复位成0000H,另外一些内部特殊功能寄存器在复位期间也将重新赋值。

工作寄存器R0到R7,累加器A,寄存器B,堆栈指针SP,程序计数器PC。

第三:程序计数器的简介

      程序计数器是用于存放执行指令的地方,故程序计数器PC指针又叫做指令计数器。为了保证程序(在操作系统中理解为进程)能够连续地执行下去,CPU必须具有某些手段来确定下一条指令的地址。而程序计数器正是起到这种作用,所以通常又称为指令计数器。 

      在程序开始执行前,必须将它的起始地址,即程序的一条指令所在的内存单元地址送入PC,因此程序计数器(PC)的内容即是从内存提取的第一条指令的地址。当执行指令时,CPU将自动修改PC的内容,即每执行一条指令PC增加一个量,这个量等于指令所含的字节数,以便使其保持的总是将要执行的下一条指令的地址。由于大多数指令都是按顺序来执行的,所以修改的过程通常只是简单的对PC加1。

(1)当程序转移时,转移指令执行的最终结果就是要改变PC的值,此PC值就是转去的地址,以此实现转移。有些机器中也称PC为指令指针IP(Instruction Pointer)。

(2)pc加1表示你所执行的是单字节指令,加2是双字节指令,也就是说执行此指令后pc将移动2个字节到下一个指令执行地址。
 

第四:ebp栈基址和esp栈顶指针的在变量堆栈时的变化

Ebp是栈基址,esp是栈顶指针。向低地址扩展是指分配内存时,是通过esp-分配的大小。

例如:加入栈基址ebp是0x00120004。一开始esp和ebp都是相同的,也为0x00120004,此时栈里是没有数据的。当我定义了一个int i,那么编译器会将esp减去4,即esp变成0x00120000。最后0x00120000到0x00120004地址中存放4个字节的i。

如果再分配的话,esp还会减少,即栈顶向低地址移动。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值