I am extending the question asked on What happens when a computer program runs? and from the discussion on Stanford CS101 site Software: Running Programs. CS101 site quotes
The machine code defines a set of individual instructions. Each machine code instruction is extremely primitive, such as adding two numbers or testing if a number is equal to zero. When stored, each instruction takes up just a few bytes. When we said earlier that a CPU can execute 2 billion operations per second, we meant that the CPU can execute 2 billion lines of machine code per second.
A program, such as Firefox, is made up of a sequence of millions of these very simple machine code instructions. It's a little hard to believe that something as rich and complicated as Firefox can be built up out of instructions that just add or compare two numbers, but that is how it works. A sand sculpture can be rich and complicated when viewed from a distance, even though the individual grains of sand are extremely simple.
What I don't understand is how Firefox window or GUI can be translated into simple CPU instructions that just add or compare two numbers? How can one know the actual instructions that CPU executes to bring up the Firefox Window? How about the user search typed into the search bar? What does this translate into CPU instructions?
If Firefox is a complicated example, how about a simple application like a Notepad?
Is it actually possible to see the all instructions being executed from running Notepad to typing ABCDEFGHIJ
and saving this as test.txt
?
As I mentioned in the comments, using a disassembler tool like objdump -d
in Linux can help you take a binary/executable file and generate the set of assembly instructions that comprises the entire program.
For instance, if you use objdump -d
on notepad.exe
(which won't be completely accurate or insightful because objdump
is for Linux and Notepad is a Windows program) you will see:
notepad.exe: file format pei-x86-64
Disassembly of section .text:
0000000140001000 <.text>:
140001000: cc int3
140001001: cc int3
140001002: cc int3
140001003: cc int3
140001004: cc int3
140001005: cc int3
140001006: cc int3
140001007: cc int3
140001008: 40 55 rex push %rbp
14000100a: 48 8d 6c 24 e1 lea -0x1f(%rsp),%rbp
14000100f: 48 81 ec d0 00 00 00 sub $0xd0,%rsp
140001016: 48 8b 05 8b 14 03 00 mov 0x3148b(%rip),%rax # 0x1400324a8
14000101d: 48 33 c4 xor %rsp,%rax
...
I'm using objdump
because I'm on Linux, but as @PeterCordes pointed out in the comments, the assembly instructions should be the same with a Windows disassembler.
The objdump
output has more than 43k assembly instructions, so deciphering what each section of assembly does would take forever. This is the entire set of instructions of what Notepad could execute. So if you want to know which assembly instructions are executed and in what order when you do something like type ABC
and save it, you would need to use some sort of tracer (e.g. gdb
) to step through only those specific executed instructions.