I've already build embedded systems PCB's using microcontrollers as stm32, stm32l, nRF51822, efm32g, most of them using arm cortex m3. And to program each one of them is usually different, i.e, the interrupt line used in one microcontroler for gpio is not the same used in another one, the registers to configure one is not the same as the other, so the code I made for one is not compatible with the other because each microcontroler link its peripherals differently with the processor.
I suppose that the equivalent of the microcontroler in the PC architecture is a motherboard right? But how the code made for a motherboard (using x86 for instance) are compatible with other motherboards? Is there a standard? Is all the interrupt lines (linked by hardware) equally for all motherboards designed to run Windows or Linux? And the IO ports are the same? Is the interface to change the clock the same?
Usually, when I go to program bare-metal (no OS) code for a microcontroler, I get its datasheets to know how can I interact with the peripherals, is there a unified reference manual for all the motherboards?
I would appreciate if someone could pointing me some references about this subject. When I look for computer architecture books, or they are focused on the processor ASIC design (instruction set, pipelines, caches, etc, which I know already) or they are are really basic stuff (like: what is a hard driver).
I think the short answer is no, motherboards aren't compatible with motherboard made for different architectures. The compiler and OS kernel abstracts the architectural difference, but the OS kernel itself had to be coded for each architecture. In particular, the part of the OS that are hardware specific is called the "driver" for that particular hardware, and it had to be coded for each architecture.
When writing code for an OS, all hardware accesses go through the OS kernel, which knows how to do hardware accesses for that particular hardware architecture. Programs don't do any interrupts themselves, but let the kernel does the actual job.
All that a program and compiler has to know is how to make a system call in a given architecture and OS, and what the system call number identifying the OS API.