当前位置:首页 > 电子 > 正文内容

C语言中将绝对地址转换为函数指针以及跳转到内存指定位置处执行

admin5年前 (2020-01-08)电子6769
1、方法一
    如果要对绝对地址0x200000进行赋值,我们可以用
      (unsigned int  * ) 0x200000 = 1234;//指针直接指向存储区地址
     那么要是想让程序跳转到绝对地址是0x100000去执行,应该怎么做?
     *( (void (*)( ))0x100000 ) ( );
    首先要将0x100000强制转换成函数指针,即:
     (void (*)())0x100000
     然后再调用它:
   *((void (*)())0x100000)();
   用typedef可以看得更直观些:
    typedef void(*)() voidFuncPtr;
   *((voidFuncPtr)0x100000)();
 
又如
如果用 C 语言,可以像下列示例代码这样来调用内核:
void (*theKernel)(int zero, int arch, u32 params_addr)
= (void (*)(int, int, u32))KERNEL_RAM_BASE; 
…… 
theKernel(0, ARCH_NUMBER, (u32) kernel_params_start); 
KERNEL_RAM_BASE 是内核在系统内存中的第一条指令的地址。
2、方法二
C语言使用函数指针跳转到程序固定地址(0x8000)执行程序的方法

使用函数指针,把一个纯数据强制转换为函数指针类型。


int main(void)
{
  void (* my_function)(void);
  //int *my_address = 0x8000;
  my_function =(void (*)())(0x8000);
  my_function();
}


#include<stdio.h>
typedef void (*funcptr)(); //funcptr为无参数,无返回值的函数指针类型
void f(void) //随便一个无参数无返回值函数
{
  printf("aaa\n");
}

int main(void)
{
  //printf("%p", f); //通过此可知道函数f的地址。不同的环境可能会不一样,
  //我的是0x401530

  (*(funcptr) 0x401530)(); //将0x401530强制转换为funcptr类型,并解引用,再
  调用,因为funcptr为函数指针类型,所以0x401530被强制转换为函数指针,
  也就是说,将地址为0x401530的东西当作函数来看待,而函数 f 的地址正好是
  0x401530,所以直接调用函数 f 。

  (*(void (*)()) 0x401530)();
  return 0;
 } 



如果带参数的呢?



#include <stdio.h>

#define my_function(a,b) ((*(void(*)(int ,char ))0x40052d)(a,b))
void ppr(int a,char b)
{
    printf("hello,word!!%d ,%d",a,b);
}
int main(void)
{
    printf("%p\r\n",ppr);

    my_function(1,2);
}



其实更简单,不适用中间变量,直接一步到位:

(*(void(*)())0x8000)();

转成汇编就占两条指令.

扫描二维码推送至手机访问。

版权声明:本文由视觉博客发布,如需转载请注明出处。

本文链接:https://feelsight.cn/post/108.html

“C语言中将绝对地址转换为函数指针以及跳转到内存指定位置处执行” 的相关文章

ESP8266在Eclipse下设置编译模式(有boot和无boot)

ESP8266在Eclipse下设置编译模式(有boot和无boot)

更改编译模式可以更改Makefile文件中的 BOOT?=new APP?=1 SPI_SPEED?=40 SPI_MODE?=QIO SPI_SIZE_MAP?=2 可以根据2A-ESP8266__IOT_SDK_User_Manual__CN_...

物联网 WIFI 一键配置原理(smartconfig) ESP8266/QCA4004

物联网 WIFI 一键配置原理(smartconfig) ESP8266/QCA4004

物联网 WIFI 一键配置原理(smartconfig) ESP8266/QCA4004 自从物联网问世以来,如何使得物 能够联网有了很多的方式,目前运用非常广的WIFI,今天就总结下自这个方面,也对于有需要的盆友也希望有抛砖引玉之效果。 来看个知乎...

锂电池充电的原理

锂电池充电的原理

    锂离子电池的充电过程可以分为四个阶段:涓流充电(低压预充)、恒流充电、恒压充电以及充电终止。     锂电池充电器的基本要求是特定的充电电流和充电电压,从而保证电池安全充电。...

stc-isp烧录 下载 协议 过程分析

一、数据封装格式 包头 标示 数据包长度 命令字...

正点原子阿波罗ST32F767试用

正点原子阿波罗ST32F767试用

一、             硬件整体介绍 1.       底板  &nb...

linux系统 硬盘自动挂载 自动格式化 脚本

mkdir /data1 mkdir /data2 mkdir /data3 mkdir /data4  mkfs.xfs /dev/sdb1 echo "/dev/sdb...

发表评论

访客

◎欢迎参与讨论,请在这里发表您的看法和观点。