This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

The volatile modifier adds instructions

The volatile modifier adds instructions to expand the variable to a 32-bit value (UXTB, UXTH, SXTB, SXTH).
It doesn't make sense. checking code online

#include "stdint.h"

struct _st
{
     uint8_t       a;
    volatile  uint8_t    b;
}st;

uint32_t test(uint8_t c)
{
    uint8_t out;
    if(st.a > c) out = st.a;
    else out = st.b; 
    return out;
};
код
test:
  ldr r2, .L3
  ldrb r3, [r2] //reading st.a
  cmp r3, r0
  bhi .L2
  ldrb r3, [r2, #1] //reading st.b
  uxtb r3, r3    // <<<<< 
.L2:
  mov r0, r3
  bx lr
.L3:
  .word .LANCHOR0
st:
Parents
  • I changed the example a little, and it turned out to be even more interesting.
    The structure now contains int8_t, which are read in two different ways.
    Simple variable "a" is read by ldrsb instruction, automatically expanded to int32_t. Because after it the "cmp" comparison instruction is used, which does not know how to work otherwise, and is a natural barrier.
    And then "b" is read with the "volatile" modifier. An instruction to read an unsigned variable is used, followed by a separate extension.

    #include "stdint.h"
    /// -Os -mcpu=cortex-m7 
    struct _st
    {
        int8_t       a;
        volatile  int8_t    b;
    }st;
    
    int32_t test(int32_t c)
    {
        int32_t out;
        if(st.a > c) out = st.a;
        else out = st.b; 
        return out;
    };
    код
    test:
      ldr r2, .L3
      ldrsb r3, [r2]
      cmp r3, r0
      bgt .L1
      ldrb r3, [r2, #1] @ zero_extendqisi2
      sxtb r3, r3
    .L1:
      mov r0, r3
      bx lr
    .L3:
      .word .LANCHOR0
    st:
Reply
  • I changed the example a little, and it turned out to be even more interesting.
    The structure now contains int8_t, which are read in two different ways.
    Simple variable "a" is read by ldrsb instruction, automatically expanded to int32_t. Because after it the "cmp" comparison instruction is used, which does not know how to work otherwise, and is a natural barrier.
    And then "b" is read with the "volatile" modifier. An instruction to read an unsigned variable is used, followed by a separate extension.

    #include "stdint.h"
    /// -Os -mcpu=cortex-m7 
    struct _st
    {
        int8_t       a;
        volatile  int8_t    b;
    }st;
    
    int32_t test(int32_t c)
    {
        int32_t out;
        if(st.a > c) out = st.a;
        else out = st.b; 
        return out;
    };
    код
    test:
      ldr r2, .L3
      ldrsb r3, [r2]
      cmp r3, r0
      bgt .L1
      ldrb r3, [r2, #1] @ zero_extendqisi2
      sxtb r3, r3
    .L1:
      mov r0, r3
      bx lr
    .L3:
      .word .LANCHOR0
    st:
Children
No data