First and foremost, please read this: Why is the gets function so dangerous that it should not be used?. So, instead of your gets(str1) line, use fgets(str1, 20, stdin) (and likewise for reading str2). Second, you should really provide a prototype (pre-declaration) of your xstrcmp before using it; a line like this before main will do: int xstrcmp(char* p1, char* p2); (or you could move the whole body of that function to before main). In your case, as the compiler will assume that it is a function returning an int, there is no major issue; but it's bad practice to use such undeclared functions and (IIRC), the option is planned for removal in a future C Standard.
Now to the logic problems in your function: There are two.
- You don't give kany value that will be used if thewhileloop finished without finding a mismatch (i.e., if the passed strings are the same);  this is a simple fix: initializekto zero, likeint k = 0;.
- When you do find a mismatch, you neither increment the p1andp2pointers, and nor do you break out of thewhileloop – so that loop will continue forever, once such a mismatch is found. To fix this, simply add abreak;statement in yourelseblock.
Here is a working version of your code that addresses these issues:
#include <stdio.h>
#include <string.h>
int xstrcmp(char* p1, char* p2); // Pre-declaration of the function
int main() {
    char str1[20], str2[20];
    fgets(str1, 20, stdin);
    fgets(str2, 20, stdin);
    printf("\n%d", xstrcmp(str1, str2));
    return 0;
}
int xstrcmp(char* p1, char* p2) {
    int k = 0; // We need to give k a value to use if we complete the loop without a mismatch
    while (*p1 != '\0' || *p2 != '\0') {
        if ((*p1 - *p2) == 0) {
            p1++, p2++;
            continue;
        }
        else {
            k = ((*p1) - (*p2));
            break; // Once we find a mismatch, we must terminate the loop after assiging k
        }
    }
    return k;
} 
Note: it is more conventional to use a loop condition like while (*p1 != '\0' && *p2 != '\0') (using && instead of ||). However, in your case, the internal loop logic (once corrected) will allow either to work: any mismatch will stop (break) the loop and, if the strings are the same, then both p1 and p2 will point to nul characters at the same time, so the test using || will still fail when it is expected to.