While the answer is fairly complex, and requires understanding the basics of electrical systems & circuits (KVL, KCL), binary numbers, and boolean logic, we can describe the process at a high level: code (represented by plain text words) is compiled, assembled and ultimately translated into a combination of Zeroes and Ones, which represent low and high voltages respectively.
When voltages are applied to materials & circuits, those voltages can change their physical properties, such as closing a circuit which supplies current to a light bulb (causing it to illuminate) or supplying current to a dc-motor which might open up a CD/DVD/Bluray/(?) Drive.
Now imagine a hypothetical 1-bit CPU, which has the ability to close a circuit and deliver current to a buzzer, making a sound. This 1-bit CPU has a single Input, which can have two values: 0 and 1.
This simple CPU has a very simple assembly language: ON and OFF, and we have a fancy programming language that provides some nicer abstractions: cpu.turnOn,cpu.turnOff.
I write my program cpu.turnOn; compile it, assemble it, and it's ready to be run. When I run the program on my CPU, the buzzer turns on.
In the real world, computers are made up of more complex systems. Instead of a single 1-bit CPU, we have 64-bit CPU, with complex instruction sets, and a myriad of devices.
To make things for a complex system to interact, these systems are made up of layers of abstractions.
The lowest layer is voltages, circuits and silicon, or what you might think of as the actual 'physical hardware.' Along side the hardware will typically sit a 'microcontroller' or a specialized processing unit that is designed to interact with the specifics of a hardware. Imagine an optical disk drive, it's microcontroller has the ability to eject the drive bay, start up the motor, align the laser, and stream data off disc.
The software that the microcontroller runs, is referred to as firmware. It's a specialized operating system that controls hardware functions and may also include an API. In the imaginary 1-bit CPU example, the program would be firmware, and the cpu.turnOn, cpu.turnOff would be the API.
Given a computer is made up of lots of hardware components (graphics, storage, communications, i/o), computers are made up of lots of specialized firmwares. For anything useful to get done with that hardware, another layer of abstraction is needed, for example to deal with Keyboards in a universal manner, or to allow mice, touchpads, and trackballs all to behave the same despite different interactions. This is where the Operating System comes in. The OS provides an API to manage groups of related devices, and provides hooks for hardware vendors to provide the translation between the OS commands, and the commands the microcontroller understand. In Windows land, this is a driver.
The next layer of abstraction above Operating Systems and Drivers, are applications, what users use to do real work (or play Fortnite). These programs are written in a myriad of languages, SDK, and toolkits, and is the reason why StackOverflow exists. Those languages compile down into executable code which the OS loads and manages, and executed by the computer.
Putting it all together with the shutdown command: the command interpreter uses an OS level API that manages system power. That API sends a notification to the rest of the OS to handle things like gracefully flushing memory buffers, saving application state, terminating communication channels, and powering off a variety of hardware systems (or more likely going into low-power consumption mode). It also uses a power driver (ACPI?) to interface with the computer's power management subsystem. This subsystem is instructed to shutdown, which in turn sends a signal to the computer's power supply to break the circuit and no longer supply power to the majority of components.
There're several interfaces between PC programs and the real world outside.
Some connect to CPU. Examples of these are Ports and hardware interrupts (IRQ). These allow sending small amounts of data (by host program request) and calling functions (interrupt handlers) based on hardware triggers (discrete line going from low to high).
There're faster interfaces for transferring massive amounts of data that bypass CPU. This is called DMA (direct memory access). These are used to transfer data to disk, network, display adapters, etc.
For port IO (opcodes IN and OUT) the software is the initiator. For IRQ, the hardware speaks up first to trigger software response.
Only device drivers are allowed to do all these. If you try doing it from the application, OS will smash it at instant. Applications connect to this world thru APIs presented by device drivers. Many of the APIs are standardalized, so you can replace actual device without having to interact differently (a printer, disk, keyboard, mouse, CRROM, ATX power supply switch in your example).
When the computer is off, it can still be turned on without physically pulling a switch, for example by a Wake on LAN signal from a network card in the computer.
Let's compare the physical and the software solutions.
When you push the button, you are actually sending a 5 volt signal to the power supply unit. This 5 volts of power never actually switches off (even when you think your computer is off). You need this 5 volts for when you push the button to turn the computer on - at which point another 5 volts is sent in to the power supply unit to tell it to switch back on.
So in actual fact, your physical button press is converted into an electronic signal in order for the power supply to do something.
When you think of things in these terms you suddenly realise that the computer doesn't need to turn its electronic signal into a physical button-push to turn off the power - that's something they've added to benefit humans (i.e. if you thought there was a tiny motor that pushed a secret internal "off" button - it doesn't exist).
So all the software needs to do is instruct an electronic signal, which triggers the power supply to enter 5 volt standby mode.
Actually, your plain text of codes does not make the computer shutdown directly. It calls a procedure of the underlying operating system. The operating system in turn invokes the ACPI/APM on your main board. This will then make the computer shut down.
How the little 1's and 0's interact with the circuits of your hardware is quite a complex subject which you could read at least one book about to completely understand it...
The leg kicking a ball is a good example. It's quite similar in a machine. The CPU is connected to all the other parts of the system, but unlike the nervous system which is a physical wiring, with all nerves being connected at once, the CPU's does not maintain a permanent connection to the rest of the system. It connects to the desired part on demand - similar to making a telephone call - all telephones have connections, but only a few are connected at any one time.
The cpu does work by running instructions - the software program. There are instruction codes that instruct the cpu to dial some part of the system. Each part has a number, and the cpu has an instruction to dial a number. Once the cpu dials that number, it sends a message to that part - the message is simply data - from one bit up to any arbitrary size block. The hardware at that location then acts on the message encoded.
In doing it like this, the cpu can control any piece of hardware using the same mechanism. The only thing that changes for each device is the number the cpu has to dial and the data the cpu sends to the device - details that are put into the software the cpu is running.
So, to turn the machine off, the cpu dials the number for the power management device, and sends it instructions to go into an appropriate power state. The hardware responds, and the PSU stops sending primary power to the motherboard.
When you write softare, you don't have to know all these details yourself. They are usually pre-packaged as ready to use code, so your software just has to say "shutdown" and the ready-made codes for this (usually in the BIOS) are executed to perform the shutdown, as outlined above.
If in case you are looking for how in general any device is made to perform its action, the device comes with firmwares stored in ROM / CHIP of the control board. The control board is used to control the device through electric signals.
Above the firmware, you will have drivers/service provider. The application will use these service providers/drivers to communicate or instruct the device to perform some action.
Click here to know more on how-firmwares-communicate-to-the-electronic-devices-to-perform-its-operations?
I have pondered the same question for quiet sometime now and come to realize that there are in fact a connection from software(fantasy) world to hardware(real) world.
Think of something as simple as circuits and switches, then think of something more abstract like an adder or ALU. Over time abstraction built on itself and gets complex in the next rom. Then comes the microcode, Opcodes, machine language then finally assembly and C. After that came BIOS, OS, drivers and GUI and hold and behold came your beloved "Shut down" button.
Software is stored in the hardware as magnetic domains on the hard drive or floppy disc, or as low and high voltages in computer chips. When you type on a keyboard, each character is converted into an electrical series of 0's and 1's which are then stored as low and high voltages in the computer chips called RAM. The low and high voltages in RAM are then converted into the magnetic domains on the hard drive or floppy disc for later reading back by the disc heads into voltages, or are stored as low and high voltages in non-volatile computer chips for later reading back. The low and high voltages represent the electrical 0's and 1's which were generated by the keyboard characters.
Its simple:The codes/software we write are electric signals represented by 0's(OFF's) and 1's(ON's) on the actual CPU.From that point think of currents and motors.
If you think software is a different creature in comparison with hardware, no explanation would satisfy you. Think software like a sequence of electric charges. All the code that you write would get stored as sequence of electrical charges either on RAM or disk. So you are NOT writing text but the sequence of electric charges. Your video card is drawing the stuff on the monitor in English to help you to understand what you are typing. In one way, perhaps truly, whatever you do on the computer is physical.
I had the same question taunting my brain since 2011 when I chose to become a Software Engineer.
As life moved on and my wish came true, I started working on different computer technologies and domains and I started answering for my own questions.
Firstly, I would define the Software as the set of automated instructions to the hardware. Instruction in this context means just the two states GoOn/GoOff or 1/0 or High/Low or True/False or Charge/NoCharge or PowerUp/PowerDown.
The working of any modern computers could be said as the instruction chain reactions of the hardware.
Why and How? Explained below,
Imagine!, you holding two wires connected to the bulb and attach them to the battery +ve and -ve. You know what happens now. Tantadaan!, Light glows up.
Here,
Hardware: Wires, bulb and the Holder.
Software/Instruction/Action: You attaching both of those wires to the battery.
Charge: Battery power.
Result: Light glows up.
In a similar way when you first turn on the computer you trigger the first instruction/action (GoOn) by pressing the button or a turning on the power switch.
Now, as I said the instructions (your software/text code converted to 1/0 instructions) drive the chain reactions in the hardware which leads your computer to function as defined in the instructions (Drivers/OS/Software).
If you wish to know further in-depth, please leave a comment down.
One key important feature here is an amplification, the electrical signals used within a computer are tiny and always flowing as triggered by the clock, and as directed and amplified by the logic gates, they can be at some point sent out to physical devices connected to the computer where they can trigger an actual physical activity. Transistors are the ingenious components used to implement logic gates and amplification of signals. They are at the centre of the software-hardware interface.
Logic gates (low-level circuitry) and the CPU (higher abstraction of logic gates) are the key answer to your question. They are basically the bridge between software and hardware.
This is my super-simplified explanation. A CPU has a clock cycle which is usually triggered by naturally occurring vibrating elements like Quartz crystals. During every cycle, it fetches an instruction from memory (the software side) and its ALU (Arithmetic Logic Unit runs some circuitry and based on the software instructions, and outputs some data which can potentially be written back to another memory location.
Now on the hardware side, every piece of hardware has firmware on it, the firmware is a bunch of logical instructions usually wired with pure circuity (logic gates, again), based on the input it can output a specific combination of electrical signals which can be amplified and used to trigger an actual physical event e.g eject disk, switch on a light, e.t.c
"How does plain text of codes make the computer do what it does?"
Let's say I write code in a text editor using any language like C++ or Java.
This code is given to the compiler and it then converts it into assembly code. Then, it's converted to binary, ie; 0's and 1's which represents digital voltages which are then fed into transistors in the hardware.