对绝对地址的操作
2014-09-27 20:03
141 查看
嵌入式系統中往往需要讓程序跳到內存的某個地址去執行,比如想讓程序跳轉到絕對地址是0x100000去執行,應該怎麼做?
這樣:
*((void (*)(void))0x100000)();
即可。
解釋一下,想讓程序跳到某個絕對地址去執行得用函數指針,這或許也是函數指針的一個妙用吧!
語句void(*)(void)聲明了一個返回值是void、無參數的函數的函數指針,這個指針沒有名字但有指向的地址。就是說地址0x100000是一個返回值是void、無參數的函數的起始點,其實就是函數名,這里也印證了函數名就是函數地址。拆開看看:
void (*)(void)0x100000
這個家伙是個指針,函數的實際地址在它指向的地方,所以需要取內容,于是就*(void (*)(void)0x100000)。這樣一來這個表達式就是這個“函數的地址了”,也就是函數名,函數名後面打個括號加上參數就行了,于是最後就是*(void (*)(void)0x100000)()。
也可以這樣理解:
首先要將0x100000強制轉換成函數指針,即:
(void (*)(void))0x100000
然後再調用它:
((void (*)(void))0x100000)();
用typedef可以看得更直觀些:
typedef void(*)() voidFuncPtr;
*((voidFuncPtr)0x100000)();
寫到這里我想到了另外一個問題:想要讀寫絕對地址0x00001234處的數據(4個字節)咋辦?
你可能很快就會這樣做:
unsigned long *p = 0x00001234;
//讀
int var1 = *p;
//寫
*p = 0x1111;
這樣不錯,不過你為了讀寫這四個字節的區域聲明了一個指針變量,指針變量本身占4個字節,如果p以後還有很多工作也就罷了,如果它從此就不再使用了,那么這樣做就純屬沒必要,還高的變量多看花了眼,可以這樣:
(*((unsigned long *)0x00001234))
//讀
int var = (int)(*((volatile unsigned long *)0x00001234));
//寫
*((volatile unsigned long *)0x00001234) = 0x1111;
嵌入式系統中常用的讀寫寄存器的方法就是這樣,比如:
#define REG_1 (*((volatile unsigned long *)0x00001234))
那么就可以隨意的操作寄存器REG_1了。
嵌入式系統中往往需要讓程序跳到內存的某個地址去執行,比如想讓程序跳轉到絕對地址是0x100000去執行,應該怎麼做?
這樣:
*((void (*)(void))0x100000)();
即可。
解釋一下,想讓程序跳到某個絕對地址去執行得用函數指針,這或許也是函數指針的一個妙用吧!
語句void(*)(void)聲明了一個返回值是void、無參數的函數的函數指針,這個指針沒有名字但有指向的地址。就是說地址0x100000是一個返回值是void、無參數的函數的起始點,其實就是函數名,這里也印證了函數名就是函數地址。拆開看看:
void (*)(void)0x100000
這個家伙是個指針,函數的實際地址在它指向的地方,所以需要取內容,于是就*(void (*)(void)0x100000)。這樣一來這個表達式就是這個“函數的地址了”,也就是函數名,函數名後面打個括號加上參數就行了,于是最後就是*(void (*)(void)0x100000)()。
也可以這樣理解:
首先要將0x100000強制轉換成函數指針,即:
(void (*)(void))0x100000
然後再調用它:
((void (*)(void))0x100000)();
用typedef可以看得更直觀些:
typedef void(*)() voidFuncPtr;
*((voidFuncPtr)0x100000)();
寫到這里我想到了另外一個問題:想要讀寫絕對地址0x00001234處的數據(4個字節)咋辦?
你可能很快就會這樣做:
unsigned long *p = 0x00001234;
//讀
int var1 = *p;
//寫
*p = 0x1111;
這樣不錯,不過你為了讀寫這四個字節的區域聲明了一個指針變量,指針變量本身占4個字節,如果p以後還有很多工作也就罷了,如果它從此就不再使用了,那么這樣做就純屬沒必要,還高的變量多看花了眼,可以這樣:
(*((unsigned long *)0x00001234))
//讀
int var = (int)(*((volatile unsigned long *)0x00001234));
//寫
*((volatile unsigned long *)0x00001234) = 0x1111;
嵌入式系統中常用的讀寫寄存器的方法就是這樣,比如:
#define REG_1 (*((volatile unsigned long *)0x00001234))
那么就可以隨意的操作寄存器REG_1了。
相关文章推荐
- MAP和FIELD伪操作定义的内存表结构(绝对地址与相对地址的区别)
- 寄存器绝对地址操作
- FormatRemoteUrl函数之asp实现格式化成当前网站完整的URL-将相对地址转换为绝对地址的代码
- 一个绝对经典的在VB中操作.ini文件的通用类源代码
- FormatRemoteUrl函数之asp实现格式化成当前网站完整的URL-将相对地址转换为绝对地址的代码
- C#返回绝对URL地址
- 一个绝对经典的在VB中操作.ini文件的通用类源代码
- 每日一课(2/75) 常用指令(传送 交换 取地址 取段 栈操作)
- DefiniteUrl asp将相对地址转换为绝对地址的代码
- JFig中如何使用绝对地址定义xml文件
- vc中把变量定义在某一绝对地址上
- 从页面中取出e-mail地址和相对链接及绝对链接的代码...
- 给初学者:VB如何操作WEB页的浏览提交———八:获取网页上的链接、图片指向地址
- wince的存储器操作与地址映射知识点滴
- 在线获取FLV真实绝对地址
- 克隆MAC地址操作实例[转贴]
- 从页面中取出e-mail地址和相对链接及绝对链接的代码...
- BEOPlayer---音色巨好,而且操作的界面也是最令类的,绝对一用难忘!!
- DefiniteUrl asp将相对地址转换为绝对地址的代码
- Asp.net在封装类中如何得到绝对地址