也就是数组中的数据是四条汇编指令
CLR A
PUSH ACC
PUSH ACC
RETI
的机器码,这样(*((void (*)())(Reset)))()就执行了(一般只对普林斯顿结构的MCU、PC、其他处理器有用—数据空间和程序空间地址统一编码)
CLR A
PUSH ACC
PUSH ACC
RETI
这样的操作。想想可不可做病毒,或者在外部存储器中(外部EEPROM、SD卡、U盘)存储一个文件,该文件就是特定程序的机器码,把这样的存储器插入到设备中时,处理器/单片机读入数据到内部SRAM,之后运行这个读入的程序
-----------------------------------------------------------------------
是的,函数名就是地址。C教材(谭浩强写的那本)上有说的,函数地址调用函数时,加不加前面那一个星号都可以,但是要注意函数指针和*、()的结合优先级,如(*pFun)()和*pFun()是不同的
void Test()
{
...
}
int main(void)
{
void (*pFun)() = Test;
(*pFun)(); /* (*pFun)()和pFun()作用一样,都是实现Test()函数调用 */
pFun();
}
-----------------------------------------------------------------------
笔误 *( ( void(*)())0x0000 ) )();左边少加了一个左括号,
(*( ( void(*)())0x0000 ) )();
{加上左括号}
int main(void)
{
unsigned char code Reset[]={0xE4,0xC0,0xE0,0xC0,0xE0,0x32}; /* 复位代码,属于机器码 */
(*((void (*)())(Reset)))(); /* 将Reset数组当函数调用 */
}
(原文件名:s.jpg)
也就是数组中的数据是四条汇编指令
CLR A
PUSH ACC
PUSH ACC
RETI
的机器码,这样(*((void (*)())(Reset)))()就执行了(一般只对普林斯顿结构的MCU、PC、其他处理器有用—数据空间和程序空间地址统一编码)
CLR A
PUSH ACC
PUSH ACC
RETI
这样的操作。想想可不可做病毒,或者在外部存储器中(外部EEPROM、SD卡、U盘)存储一个文件,该文件就是特定程序的机器码,把这样的存储器插入到设备中时,处理器/单片机读入数据到内部SRAM,之后运行这个读入的程序
-----------------------------------------------------------------------
类似的技术用得很多
而且不限于嵌入式
比如软件反破_解的花指令
虚拟机字节码Just In Time优化的ASM emitter
而且其实你程序存储在媒体上
本身就是以这种形式
用Linux就知道
同样的文件
设置成可执行属性才会当做程序执行
不然就是数据。。。。
一周热门 更多>