我们本周在这里遇到了有趣的问题.
我们在C上使用哈佛架构嵌入式平台,该平台具有16位数据地址和32位代码地址.
使用函数指针时会出现此问题.如果你有像这样的代码
if (fp) fp();
Run Code Online (Sandbox Code Playgroud)
要么
if (fp != 0) fp();
Run Code Online (Sandbox Code Playgroud)
一切都好.
但是如果你有像这样的代码
if (fp != NULL) fp();
Run Code Online (Sandbox Code Playgroud)
然后,因为NULL
定义为(void *) 0
,编译器(在这种情况下为gcc)a)不警告,b)对函数指针进行16位比较而不是32位比较.只要你的函数指针没有发生在64k边界上,所以所有底部的16位都是0就很好.
目前我们有大量的代码包含对NULL的显式检查.它们中的大多数将是数据指针,但其中一些将是函数指针.快速grep != NULL
或== NULL
显示超过3000个结果,许多人通过手动检查.
那么,我们现在想要的也是
找到比较函数指针(但不是数据指针)的所有情况的方法(所以我们可以将它们与我们定义为32位0的FP_NULL进行比较),或者
以这样的方式重新定义NULL,以便它做正确的事情.
(或者,我想,更新我们的gcc端口以检测并正确处理这种情况).
我无法想到任何适用于1的方法.我能想到的唯一方法是将NULL重新定义为0函数指针,这对于绝大多数针对数据指针的比较来说都是非常浪费的.(32位比较是4条指令,16位比较是1条指令).
有什么想法或建议吗?
在设计个人计算机时,为什么基于冯·诺依曼架构的计算机体系结构优于哈佛体系结构; 哈佛架构用于设计基于微机的计算机系统和基于DSP的计算机系统?
哈佛架构计算机具有单独的代码和数据存储器.这是否使它们免受代码注入攻击(因为数据不能作为代码执行)?
在某些体系结构上,可能需要为其他相同的对象提供不同的指针类型.特别是对于哈佛架构CPU,您可能需要以下内容:
uint8_t const ram* data1;
uint8_t const rom* data2;
Run Code Online (Sandbox Code Playgroud)
特别是这对于PICs的MPLAB C18(现已停产)中ROM/RAM指针的定义如何.它甚至可以定义如下内容:
char const rom* ram* ram strdptr;
Run Code Online (Sandbox Code Playgroud)
这意味着RAM中的指针指向RAM中指向ROM中的字符串的指针(使用ram
不是必需的,因为默认情况下,这个编译器在RAM中,为了清楚起见,所有内容都添加了).
这种语法的好处是,当您尝试以不兼容的方式分配时,编译器能够提醒您,例如ROM位置的地址到指向RAM的指针(如此类似data1 = data2;
,或者将ROM指针传递给函数)使用RAM指针会产生错误).
与此相反,在AVR-8的avr-gcc中,没有这种类型的安全性,因为它提供了访问ROM数据的功能.无法区分RAM指针和指向ROM的指针.
在某些情况下,这种类型的安全性对于捕获编程错误非常有益.
有没有办法以某种方式向指针添加类似的修饰符(例如通过预处理器,扩展到可以模仿这种行为的东西)来实现此目的?甚至是一些警告不正当访问的东西?(在avr-gcc的情况下,尝试在不使用ROM访问功能的情况下获取值)
我正在使用以下配置的笔记本电脑.处理器:Intel(R)Core(TM)i5-4300U CPU @ 1.90GHz 2.49GHz RAM:8GB系统类型:64位OS,基于x64的处理器
Windows Edition:Windows 8.2 Enterprise
当我阅读有关CPU架构的内容时,我想知道计算机中遵循的CPU架构是什么?
我知道这很接近于"愚蠢问题"类别,但我一直在研究如何在AVR 8-bit上启动加载后执行机器代码,并且已经了解到AVR 8上使用的哈佛架构 - 位MCU使得无法从闪存以外的任何地方执行代码.那么如何使用内联asm在运行时引入新的可执行代码呢?