Hello people, It's been a long time....
I've been experimenting with inline assembly for a bit (again). I just realized that the
force_read() function isn't really correct (according to my understanding at least) when optimizations come into the picture.
Here is the function again:
Code:
static void force_read(uint8_t *p)
{
asm volatile("" : : "r"(*p) : "memory");
}
Let us assume that the compiler inlines it, and we finally get:
Code:
static inline void force_read(uint8_t *p)
{
asm volatile("" : : "r"(*p) : "memory");
}
It is my understanding that a call to
force_read would not really guarantee a
memory read. Consider this program:
Code:
inline void force_read(int* address)
{
asm volatile ("": :"r"(*address):"memory" );
}
int main()
{
int a;
scanf("%d",&a);
//I'm doing some calculations with a
a *= 12432;
a += 1231;
force_read(&a); //This shouldn't actually compile to a memory read
}
As expected, Godbolt gives me:
Code:
.LC0:
.string "%d"
main:
subq $24, %rsp
movl $.LC0, %edi
xorl %eax, %eax
leaq 12(%rsp), %rsi
call __isoc99_scanf
imull $12432, 12(%rsp), %eax
addl $1231, %eax
movl %eax, 12(%rsp)
xorl %eax, %eax
addq $24, %rsp
ret
Clearly, there is no "forced read"...
I would have guessed that a better function would have been:
Code:
inline void force_read(int* address)
{
asm volatile ("mov (%[addr]) , %%rax": :[addr]"m"(address):"memory","rax" ); //Do we even need the memory clobber??
}
Is my understanding correct?