void abc(void)
{
    int a;
    printf("%d\n", a);
}
You are using a uninitialized, which is undefined behaviour. This means anything could happen, including (but not guaranteed to) the memory allocated for a in abc() still holding some previous value (i.e. the one assigned during xyz()).
A different thread could have mangled that memory. It could have been zeroed-out when you returned from xyz(). The system could be running a type of RAM that "forgets" unused memory, replacing the previous value with random noise. Do not ever touch undefined behaviour.
It might be a bit less confusing if you rename one of the two variables to something else than a. That they have the same name has no impact here; they are the first int declared in the respective function, which -- on your specific architecture -- resulted in them occupying the same memory address. This is a coincidence, not something the language guarantees. I.e., it is not defined to happen.