#include <cstdio>
int main() {
int a, b, c;
const char* str = "hello world";
asm volatile (
R"(mov %0, 1
mov %1, 2
mov %2, 3
call puts)"
:"=&r"(a),
"=&r"(b),
"=&r"(c)
:"D"(str)
:"cc","memory"
);
printf("%d, %d, %d\n", a, b, c);
}
and the complier result is like this(by gcc12.2, the options are -O3 -masm=intel
)
.LC0:
.string "hello world"
.LC1:
.string "%d, %d, %d\n"
main:
sub rsp, 8
mov edi, OFFSET FLAT:.LC0
mov esi, 1
mov edx, 2
mov ecx, 3
call puts
mov edi, OFFSET FLAT:.LC1
xor eax, eax
call printf
xor eax, eax
add rsp, 8
ret
the values (1, 2, 3 in this code) were not saved to memory from the register and they were not successfully passed to printf
as well, even if when I turned off the optimization.
so the output is like this, which is obviously undefined-behaviour.
hello world
4202511, 0, 4096
Why does this problem occur?
#include <cstdio>
int main() {
int a, b, c;
const char* str = "hello world";
asm volatile (
R"(mov %0, 1
mov %1, 2
mov %2, 3
call puts)"
:"=&m"(a),
"=&m"(b),
"=&m"(c)
:"D"(str)
:"cc","memory"
);
printf("%d, %d, %d\n", a, b, c);
}
If I change the code from "=&r" to "=&m", it can work well as expected. but is there any possibility to solve this problem while passing the a, b, c through register?
the short link of the code above is https://godbolt.org/z/W6xYcdd9c and https://godbolt.org/z/9dceGrfM1