C has no concept of a void value; that's an error. void* is just a compile-time-only placeholder for "unspecified, cast before using".  i.e. a generic pointer value.  It would be meaningless to dereference it in C or in asm, that's why compilers reject it.
An int is fixed width and uses all the bits to represent a number's value, like the simple / normal way of using a register in assembly. It can't hold anything else to indicate "null" or "undefined". If you want something like perl where you can undef $foo, you'd want something like C++ std::optional, like an <int, bool> pair of values. An int in most languages must be a number, not some "oops I'm not actually an int" indicator.
(Although rare ISAs do have trap values, e.g. one's complement machines that disallow the all-ones bit-pattern for signed integers, instead of having it work as a negative 0.  But on most ISAs only floating-point values can be NaN - a special bit-pattern that means "not a number".)
C also doesn't have a null keyword. It has NULL as a preprocessor macro (which can be #defined as ( (void*)0 ) or even just 0).  (Fun fact: ISO C actually allows implementations to use any bit-pattern they want as the runtime value of a null pointer, with compile-time translation of integer 0 in a pointer context to that bit-pattern.)  But all normal implementations on modern CPUs just use 0.  Like mov x0, #0 (AArch64).  So at least one part of you question does have an answer.
So basically you can't do any of these things in C because there literally isn't any meaning to them, and you can't do them in asm either.  There isn't some layer of magic underneath which C compilers are denying you access to.
Write C that can actually compile and look at the asm output (https://godbolt.org/ and How to remove "noise" from GCC/clang assembly output?)