我查看了微芯片的AES示例。他们编写以下代码段:
bool AES_encrypt(uint8_t * plaintext, uint8_t * ciphertext, uint8_t * key)
{
bool encrypt_ok;
uint8_t * temp_key = key;
for(uint8_t i = 0; i < AES_BLOCK_LENGTH; i++){
AES.KEY = *(temp_key++);
}
为什么它们将指针复制到临时变量中?我在Atmel Studio和反汇编程序以及这两个案例中都进行了验证
bool AES_encrypt(uint8_t * plaintext, uint8_t * ciphertext, uint8_t * key)
{
bool encrypt_ok;
/* Load key into AES key memory. */
uint8_t * temp_key = key;
for(uint8_t i = 0; i < AES_BLOCK_LENGTH; i++){
AES.KEY = *(temp_key++);
}
bool AES_encrypt(uint8_t * plaintext, uint8_t * ciphertext, uint8_t * key)
{
bool encrypt_ok;
/* Load key into AES key memory. */
for(uint8_t i = 0; i < AES_BLOCK_LENGTH; i++){
AES.KEY = *(key++);
}
产生相同的汇编代码(-O1选项)。那么此符号的目标是什么?
答案 0 :(得分:5)
正如您所注意到的,在优化的构建中,没有任何性能优势或劣势,任何值得付出代价的编译器都将在优化的早期将两者降低到几乎完全相同的IR。
这可能只是一个样式选择,有些人发现直接修改参数会令人困惑,他们更喜欢保留它们在整个函数中的位置;双重,因为这是示例代码,所以它意味着所有级别的程序员都可以轻松理解。
此方法的其他优点包括以下事实:添加引用原始值(可能是debug语句)的代码或在调试版本中的调试器中检查原始值更加容易。
答案 1 :(得分:0)
不修改函数调用的参数(即将其用作局部变量)被认为是一种好习惯。这可能是使用临时变量temp_key
的原因,因为指针在此处递增:
AES.KEY = *(temp_key++);
这不是不是,它与更改指针目标的值(此处的下降投票者可能已完成)相混淆。当然,这是惯例。
另请参见此处的讨论:Using function arguments as local variables
如您所见,这与实际的汇编程序代码没有任何区别,因此他们决定遵循此范式,这有助于使概述保持复杂的功能。