how a compiler targets an ISA
A compiler is a translator that turns the high-level code a human writes (in C, Rust, Go, and so on) into the exact machine instructions a particular ISA understands. You write 'a = b + c' once, naturally; the compiler rewrites that into the specific load, add, and store instructions of the target ISA, choosing real registers and laying out memory. Targeting an ISA means generating code that obeys that ISA's contract — its instructions, its registers, its calling convention — so the resulting program runs on chips of that family.
Walk through a tiny slice of the job. Given 'a = b + c' where the variables live in memory, the compiler must: decide which registers to use, emit a load to bring b into a register, a load to bring c into another, an add to combine them, and a store to write a back — all in the target ISA's actual instruction encodings. It also follows the ISA's calling convention so functions can call each other (which registers pass arguments, which must be preserved), and it picks addressing modes and immediates that fit the instruction formats. The same source program, compiled for two different ISAs, produces two completely different streams of machine instructions.
This is the everyday meaning of the ISA as the hardware/software handshake: the compiler is the software side reaching across to the hardware, and the ISA is the agreed language they meet in. It is also why one ISA can host a whole world of software — anything with a compiler back end for that ISA can run on it. An honest note: the compiler does far more than mechanical translation. To make the simple instructions of a RISC machine competitive it works hard at optimization — keeping hot values in registers, reordering and eliminating instructions, unrolling loops — which is a big part of why simple ISAs perform so well in practice.
Source: 'a = b + c'. Compiled for RISC-V it might become 'lw x5, 0(x10)' (load b), 'lw x6, 4(x10)' (load c), 'add x5, x5, x6' (add), 'sw x5, 8(x10)' (store a). One line of C, four target instructions.
The compiler turns one source line into the target ISA's real load/compute/store instructions.
The compiler is not a dumb word-for-word translator. Much of a fast program's speed comes from compiler optimization — register allocation, reordering, removing redundant work — which is precisely how simple RISC instructions stay competitive.