zoukankan      html  css  js  c++  java
  • 是否可以通过绝对内存地址进行参数赋值与函数调用---转载

    同一个数可以通过不同的方式表达出来,对于函数的访问,变量的赋值除了直接对变量赋值以外,还可以通过绝对内存地址进行参数赋值与函数调用。

    (1)       通过地址修改变量的值

    int x;

    int *p;

    printf("%x ",&x);

    p=(int *)0x0012ff60;

    *p = 3;

    printf("%d ",x);

    程序的输出结果为:

    12ff60

    3

    程序首先输出变量x所在地址为十六进制的0x12ff60(本来应该为8位的十六进制数,高位为0则省略掉),然后定义一个指针变量,让它指向该地址,通过指针变量的值来修改变量x的值。

    示例代码:

    int *ptr=(int*)0xa4000000; 

    *ptr=0xaabb;

    printf("%d ",*ptr);

    以上程序会崩溃,因为这样做会给一个指针分配一个随意的地址,很危险,所以这种做法是不允许的。

    (2)       通过地址调用函数的执行

    #include <iostream>

    using namespace std;

    typedef void(*FuncPtr)() ;

    void  p()

    {

           printf("MOP ");

    }    

    int main()

    {

           void (*ptr)();

           p();

           printf("%x ",p);

           ptr = (void (*)())0x4110f0;

           ptr();//函数指针执行

           ((void (*)())0x4110f0)();

           ((FuncPtr)0x4110f0)();

           return 0;

    }

    程序执行结果如下:

    MOP

    4110f0

    MOP

    MOP

    MOP

    首先定义一个ptr的函数指针,第一次通过函数名调用函数,输出Mop,打印函数的入口地址,函数的入口地址为4110f0。然后给函数指针ptr赋地址值为p的入口地址,调用ptr,输出Mop。接着的过程是不通过函数指针直接执行,仍然使用p的入口地址调用,输出为MOP。最后是通过typedef调用的直接执行。

    函数名称、代码都是放在代码段的,因为是放在代码段,每次会跳到相同的地方,但参数会压栈,所以函数只根据函数名来获取入口地址,与参数和返回值无关。无论参数和返回值如何不同,函数入口地址都是一个地方。

    对以下程序进行分析如下:

    #include <stdio.h>

    int  p(int a,int b)

    {

           return 3;

    }  

    int main()

    {

           printf("%x ",p);

           int a = p(2,3);

           printf("%d ",p);

           int b = p(4,5);

           printf("%x ",p);

           return 0;

    }

    程序输出结果如下:

    411159

    4264281

    411159

    十六进制的411159转换成十进制的值为4264281。程序中打印的p的入口地址,无论p是否调用函数,入口地址都没有改变。

    分析如下代码:

    #include <stdio.h>

    int p(int a,int b)

    {

           return ((a>b)?a:b);

    int main()

    {

           int (*ptr)(int ,int);

           ptr = (int (*)(int,int))0x411159;

           int c = ptr(5,6);

           printf("%d ",c);

           return 0;

    }

    程序输出为

    6

    通过函数指针调用有返回值和参数的函数,不适用函数名,而是用函数入口地址调用。

    函数存放在内存的代码区域内,也有地址,一个函数在编译时被分配一个入口地址,将这个入口地址称为函数的指针,函数的地址就是函数的名字。

    函数指针不能指向不同类型或是带不同形参的函数。

    参考链接:

    http://www.jobcoding.com/basic-knowledge/absolute-address-function-call/

    http://www.jobcoding.com/(<<程序员面试笔试宝典>>官网)

    方法一:

    *(int *)0x6789 = 0x0080; //直接把0x0080赋值给地址为0x6789的单元
    int m;
    m = *(int *)0x6789;        //从地址为0x6789的单元取值赋给变量m
    ----------------------------------------------------------------------------


    方法二:
    int *p, m;
    p = (int *)0x6789;
    *p = 0x0080;
    m = *p;

    想让程序跳转到绝对地址是0x100000的代码去执行,应该怎么做?
    网上有三种答案(本人没有验证):
    第一种:  *((void (*)( ))0x100000 ) ( );

    第二种:    ((void (*)())0x100000)() 或者 (*((void (*)())0x100000))()
             源地址:http://topic.csdn.net/u/20111104/19/d1fdba26-c2fb-4f1c-836b-d537b5adc3b2.html

    第三种:
    typedef  void (*func)(void);
              func f = (func)1000000;    
              f();

  • 相关阅读:
    C#根据html生成PDF
    Oracle 存储过程异常处理
    Oracle事务之一:锁和隔离
    跨域解决方案一:使用CORS实现跨域
    AJAX POST&跨域 解决方案
    使用 jQuery Deferred 和 Promise 创建响应式应用程序
    jQuery:多个AJAX/JSON请求对应单个回调并行加载
    解决td标签上的position:relative属性在各浏览器中的兼容性问题
    盘点8种CSS实现垂直居中水平居中的绝对定位居中技术
    JQuery-UI Dialog下使用服务器端按钮失效
  • 原文地址:https://www.cnblogs.com/followyourdream/p/3370066.html
Copyright © 2011-2022 走看看