c语言跳转地址,读写地址

跳转某个地址执行

最近看指针,发现有个奇淫方法,直接跳转执行某个地址执行程序。

例如:要跳转0x1000地址执行代码,代码是 ((void)(*)(void))0x1000)()

注意:以下测试方法在esp32单片机上执行,在linux上,由于每个应用都是虚拟内存,所以无法通过地址跳转执行某段程序。

为什么会这样子可以直接跳转到某个地址执行程序呢?首先先看一个demo。

void print(void){
    printf("this is a test\r\n");
}
void app_main(void)
{
    printf("Hello world!\n");

    /* Print chip information */
    esp_chip_info_t chip_info;
    esp_chip_info(&chip_info);
    printf("This is %s chip with %d CPU core(s), WiFi%s%s, ",
            CONFIG_IDF_TARGET,
            chip_info.cores,
            (chip_info.features & CHIP_FEATURE_BT) ? "/BT" : "",
            (chip_info.features & CHIP_FEATURE_BLE) ? "/BLE" : "");
    void (*function_p)(void);
    function_p=print;
     printf("The address of function = %d !\n", (int )function_p);
     vTaskDelay(100);
     printf("here\r\n");
     ((void (*)(void))1074602104)();
     (*function_p)();
    // printf("print=%p\r\n",function_p);
}

以上执行结果是

Hello world!
This is esp32 chip with 2 CPU core(s), WiFi/BT/BLE, The address of function = 1074602104 !
here
this is a test
this is a test

由以上代码可知,

该行代码 function_p=print; 是把print函数首地址传递给function_p指针。

function_p指针指向地址是1074602104,即也是print函数首地址。

然后看这一句代码((void (*)(void))1074602104)();

void (*)(void)是函数指针,((void (*)(void))1074602104意思是把1074602104转成函数指针,那么程序可以调准到0x1074602104

一般采用高级语言编程后者写纯软件时不会遇到让程序绝对跳转执行,但是涉及到底层开发时候,会用到该方式,比如STM32 IAP在线程序升级过程中,在写bootloader程序时就要让程序跳到绝对地址。

指定地址读写入值

想在某一个地址读写数据,发放实现如下

方法一:

int *p;
p=(int *)0x10000;
*p=1234;

该方法时把p指向0x10000地址,然后给p赋值1234

方法二:

*(int *)0x10000=1234

同样该方法直接向0x10000地址赋值1234.

请看以下demo

/* Hello World Example

   This example code is in the Public Domain (or CC0 licensed, at your option.)

   Unless required by applicable law or agreed to in writing, this
   software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
   CONDITIONS OF ANY KIND, either express or implied.
*/
#include <stdio.h>
#include "sdkconfig.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_system.h"
#include "esp_spi_flash.h"

void app_main(void)
{
    printf("Hello world!\n");

    /* Print chip information */
    esp_chip_info_t chip_info;
    esp_chip_info(&chip_info);
    printf("This is %s chip with %d CPU cores, WiFi%s%s, ",
            CONFIG_IDF_TARGET,
            chip_info.cores,
            (chip_info.features & CHIP_FEATURE_BT) ? "/BT" : "",
            (chip_info.features & CHIP_FEATURE_BLE) ? "/BLE" : "");

    printf("silicon revision %d, ", chip_info.revision);

    int i=0;
    printf("address=%p\r\n",&i);
    float *p;
    p=(float *)0x3ffb468e;
    (*p)=1245;
    printf("value=%f\r\n",(*p));
/*********second************************/
    *(int *)0x3ffb479f=12345;
    printf("value=%d\r\n",*(int *)0x3ffb479f);

}

运行结果如下

Hello world!
This is esp32 chip with 2 CPU cores, WiFi/BT/BLE, silicon revision 1, address=0x3ffb467c
value=1245.000000
value=12345

注意:并不是所有地址都合法的,我这里想读取变量i的地址,i的地址前后一般都可以读写。

一般编程用不了该方法,但是在单片机对外设进行读写操作时候可能会用到。

  • 7
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值