How can I access an interrupt vector located at the machine's location 0?
How can I access an interrupt vector located at the mac开发者_如何学Chine's location 0? If I set a pointer to 0, the compiler might translate it to some nonzero internal null pointer value.
If you're working in a domain where you need to read/write vectors at address zero (I guess you're on some kind of embedded system?), then you will find lots of what you're doing will be outside a general straight-down-the-middle interpretation of the 'C' standard.
You can pretty safely assume that embedded compilers will generate accesses to the addresses you put into pointers, and not magically change their contents.
However, you can't always assume that a physical address zero in a datasheet is what the processor accesses when you read/write address zero. If there's an MMU in the processor, then you might need to go through a logical -> physical mapping process of some kind, and even if there isn't a full MMU, many modern small embedded processor play games with the address space around interrupt vectors (booting out of flash and then optionally remapping that part of the address space to RAM, for example.)
You are correct that depending on your C implementation, the internal null pointer might not be 0. But is usually is. If you want to be very safe, you can typecast the value, or use memset()
.
uintptr_t zerobits = 0;
void *pointer1 = (void *)zerobits;
or:
void *pointer2;
memset(&pointer2, 0, sizeof pointer2);
Since whatever is at location 0 is obviously machine dependent, you're free to use whatever machine-dependent trick will work to get there. Read your vendor's documentation. It's likely that if it's at all meaningful for you to be accessing location 0, the system will be set up to make it reasonably easy to do so. Some possibilities are:
Simply set a pointer to 0. (This is the way that doesn't have to work, but if it's meaningful, it probably will.) Assign the integer 0 to an int variable, and convert that int to a pointer. (This is also not guaranteed to work, but it probably will.) Use a union to set the bits of a pointer variable to 0:
union {
int u_p;
int u_i; / assumes sizeof(int) >= sizeof(int *) */
} p;
p.u_i = 0;
Use memset to set the bits of a pointer variable to 0:
memset((void *)&p, 0, sizeof(p));
Declare an external variable or array
extern int location0;
and use an assembly language file, or some special linker invocation, to arrange that this symbol refers to (i.e. the variable is placed at) address 0.
精彩评论