Search code examples
cassemblyavr

Using temp value for pointer in function


I viewed the AES example from microchip. They write the following code segment:

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++);
}

Why do they copy the pointer in a temporary variable? I verified it with Atmel studio and the dissassembler and both of this cases

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++);
}

result in the same assembler code (-O1 option). So what is the goal for this notation?


Solution

  • As you noticed, in an optimized build there's no performance advantage or disadvantage whatsoever, any compiler worth its salt will reduce both of them to pretty much the exact same IR in the early stages of optimization.

    It may just be a stylistic choice, some people find it confusing to modify the parameters directly, and they prefer to leave them as they are throughout the whole function; doubly so as this is example code, so it's meant to be easily understandable by programmers of all levels.

    Extra advantages to this approach include the fact that it's easier to add code that refers to the original values (possibly debug statements) or to inspect the original value in a debugger in debug builds.