Edw*_*inW 21 c function aes volatile void
从语法的角度来看,我已经看过"volatile"关键字在C++函数中有多少用法?关于在函数上使用volatile关键字,但没有明确解释该问题的案例1做了什么.只有一位受访者表示这似乎毫无意义/无用.
然而,我不能完全接受这种说法,因为GNUC的AES软件实现已经使用了几年,它们有许多这样的功能:
INLINE volatile void functionname( /* ... */ ) {
/* ... */
asm( /* ... */ ) // embedded assembly statements
/* ... */
}
Run Code Online (Sandbox Code Playgroud)
必须有这种用法的原因.谁能:
一.告诉我原来的原因是什么; 和
乙.现在如何达到理想的效果?
我正在使用Ubuntu和GCC 4.6.3.
void fatal( /* ... */ ) { /* ... */ exit(1); }
typedef void voidfn ();
volatile voidfn fatal;
Run Code Online (Sandbox Code Playgroud)
这将允许编译器识别'致命'不会返回.
但是这种情况似乎不适用于AES代码.自从我在集会上做了很多事以来,已经有很长一段时间了,但我想我会认识到跳跃或类似的事情.
Chr*_*odd 12
根据gcc文档(直到2015年2月), volatile void作为C中的函数返回值(但不是在C++中)等效__attribute__((noreturn))于函数,并告诉编译器函数永远不会返回.
C99标准在§6.7.3/ 3中说明了这一点:
与限定类型关联的属性仅对作为左值的表达式有意义.114)
114)实现可以放置
const不在volatile只读存储区域中的对象.此外,如果从不使用其地址,则实现不需要为这样的对象分配存储
§6.2.5/ 19说:
该
void类型包含一组空值; 它是一种不完整的类型,无法完成.
§6.3.2.1/ 1说:
的左值是与一个对象类型或比其他的不完整类型的表达式
void; 53) [...]
因此,void不是左值,所以类型限定符(const,volatile,和restrict)是没有意义的类型的表达式void.所以,在任何兼容C99编译器,const void并且volatile void是没有意义的(虽然指针,以const void和const volatile 是有意义的).
此外,§6.9.1/ 3的约束不允许函数返回合格类型void:
函数的返回类型应该是
void数组类型以外的对象类型.
由于这是一个约束,因此符合标准的编译器必须发出诊断(第5.1.1.3/1节).因此volatile void在C99中不允许返回函数.
至于volatile void可能曾经做过的事情,我不知道也无法真正推测.我猜你正在寻找的AES代码可能只是旧的,从未被清理过.
https://github.com/nmoinvaz/minizip/blob/master/aes/aes_via_ace.h 见第323到333行,以及第399到492行.还有很多其他地方可以找到这段代码,这只是第一个我绊倒了.
http://www.open-std.org/jtc1/sc22/wg14/docs/rr/dr_113.html 谢谢@ouah!
http://opencores.org/ocsvn/openrisc/openrisc/trunk/gnu-old/binutils-2.18.50/gas/testsuite/gas/i386/padlock.d 打开搜索"f3 0f a7",将操作码标识为专门的加密操作.
GCC的"信息"文档.
volatile void function(...)并不严格符合C99.(感谢@Adam和@ouah.@Adam深入研究C99规范,以及@ouah将我指向上面列出的DR.)
GCC __attribute__((noreturn))在版本2.5中添加了作为替代版本volatile void,但是volatile void在版本4.6.3中继续接受以支持与版本2.5之前的编译器的代码兼容性.(海湾合作委员会文件.)
上面引用的代码确实将控制权返回到调用它的位置,因为指令似乎不操纵地址寄存器,也不执行跳转命令.相反,它们将各种值加载到32位寄存器中.(代码检查.)
第323行到第333行中的命令实现了支持加密操作的特殊操作码.(代码检查加'挂锁'代码.)
使用汇编函数的代码显然希望它们返回.(代码检查.)
该noreturn属性告诉编译器函数没有返回,因此编译器可以根据它进行优化.(海湾合作委员会文件.)
从GCC文档中:在调用noreturn函数之前,不要假设调用函数保存的寄存器已恢复.
这是与同事的讨论,最终让我陷入困境.当函数声明它不会返回时,编译器必须做一些不同的事情.对GCC文件的审查证实了这一点.
你需要问自己以下问题.
问题: AES代码专门将值加载到32位寄存器中,并对它们执行操作.如何将答案返回到其余代码?
答案: GCC优化意味着调用函数的寄存器(否则在返回时会覆盖这些值)不会被保存.汇编语言函数中的计算结果保留在寄存器中,供后续代码使用.
几乎不管它.您可能唯一要做的就是volatile void简单地替换返回类型void,并将noreturn属性添加到函数中.从理论上讲,这应该具有完全相同的效果.在实践中,它没有破坏,不修复它.
绝对不鼓励广泛使用这种技术.首先,它取决于每个编译器的自定义.其次,它取决于那些编译器没有改变他们如何处理"不归"的情况.第三,它可能会让后续的维护者感到困惑.
这种情况的唯一情况是,当你利用高度专业化的机器代码,以实现速度不可能的改进.即便如此,它应该与权衡取舍平衡.
在此示例中,仅支持两个编译器,并且仅当机器具有特定的硬件支持才能利用.否则,它全部通过标准C代码处理.这是很多努力.确保它在你做之前付清.
| 归档时间: |
|
| 查看次数: |
13271 次 |
| 最近记录: |