Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

I'm trying to really understand how exactly a high-level language is converted into machine code and then executed by the cpu.

I understand that the code is compiled into machine code, which is the low level code that a CPU can use. If I have an assignment statement say:

x = x + 5;
y = x - 3;

Does the CPU execute each line one at a time? So it will first execute the x = x + 5; instruction and then the next instruction the CPU will execute is the y = x- 3; I'm really trying to understand the execution process and how the code I write is actually execute by the CPU.

share|improve this question
    
You may want to try to understand a design of one of the open source CPUs, there are some really simple stack-based implementations like excamera.com/sphinx/fpga-j1.html - they're much simpler than the 3-address architectures like in your example. –  SK-logic Jan 5 '12 at 17:11
2  
When I got into this business, this would have had simple and well-defined answers. Nowadays, CPUs are extremely complicated and do all sorts of things to increase processing power. –  David Thornley Jan 5 '12 at 18:50

4 Answers 4

up vote 12 down vote accepted

The lines of code have nothing to do with how the CPU executes it. I'd recommend reading up on assembler, because that will teach you a lot about how the hardware actually does things. You can also get assembler output from many compilers.

That code might compile into something like (in a made up assembly language):

load R1, [x] ; meaning load the data stored at memory location x into register 1
add R1, 5
store [x], R1 ; store the modified value into the memory location x
sub R1, 3
store R1, [y]

However, if the compiler knows that a variable isn't used again, the store operation may not be emitted.

Now for the debugger to know what machine code corresponds to a line of program source, annotations are added by the compiler to show what line corresponds to where in the machine code.

share|improve this answer
    
Why not? A 3-address architecture will have instructions like ADD Rx, Rx, $5 and SUB Ry, Rx, $3 (assuming that x and y variables had been mapped into registers). You're describing a load/store RISC approach. –  SK-logic Jan 5 '12 at 17:14
1  
@SK-logic: While that may happen for very simple lines of code in very simple programming languages with data types and operations the CPU happens to support well enough, it's nowhere the general case. It's convenient for experts, but first it's important to realize the machine code instructions generally bear little resemablence to lines of code in a high-level lanugage. –  delnan Jan 5 '12 at 17:47
    
@SK-Logic: that only works for this particular example. In general, however, maxpolun is right. High-level language statements must be translated to a lower level language, with more "red tape" needed in order to do conceptually simple stuff. I guess the OP was asking for an example of this transformation. –  Andres F. Jan 5 '12 at 17:58
1  
@SK-Logic: the OP started his question with "I'm trying to really understand how exactly a high-level language [...]" –  Andres F. Jan 5 '12 at 18:37
1  
@SK-logic The context is "If I have an assignment statement say: [code snippet] Does the CPU execute each line one at a time?" - seems to me like it's intended to be source code in a non-assembler language. More generally, I see no indicator of an understanding of how low-level machine code is, and some phrasings (such as talking of lines) indicate some misconceptions. That's not as impossible as you imply, not everyone had the pleasure of being tossed head first at some simple microcontrollers (like me and apparently others). Perhaps Frankie should clarify. –  delnan Jan 5 '12 at 18:53

No, there is no one-to-one mapping between code lines / instructions in higher and lower level languages. In fact, both lines above are translated into multiple machine code instructions, like

  1. load a value from a certain memory address into a register
  2. modify the value
  3. write it back to memory

The actual details of these instructions vary between platforms.

This is the basic view of things. However, to further complicate issues, modern CPUs apply techniques like execution pipelines, out-of-order execution and multiple cores, among others. These result in the CPU doing multiple things at once, e.g. pipelines process different phases of subsequent instructions in parallel within the same processing unit, while multiple cores may process independent instructions in parallel.

share|improve this answer

You should look in great details in a book to find more details on how it works, possibly a compiler class as well.

Basically, your question is focusing on 2 different aspects.

1) How is the code translated into machine code?

2) When/how is the code computed using parallelization?

The answer to 1) depends on the language you use (although for your example is trivial so the output would be the same). The way the compiler does the translation to machine code is one of the force of the language. Besides, there are several concerns that need to be taken into account in your example, the code should load the data into memory, store it, etc.

Finally parallelization is a features that you can force from a programming point of view, but in a nutshell, some processors might try to think that some portion of code can be run at the same time, because they are independent. In your case, clearly, it's not the case, as you need to execute the statements sequentially, so no, it will not run at the same time.

share|improve this answer

It depends.

In the early days of really simple machines, yes, code executed one line at a time. As machines got bigger, faster, and more complex, you started to see both the ability to execute multiple instructions simultaneously and memory reads and writes taking a lot longer than operations on registers.

Optimizing compilers had to take this into account, and the lines you give could be executed "more or less" in parallel, with one part of the processor working on the computation of y, while another part was storing the previously-computed new value of x (and the computation of y was using that new value from the register).

The Control Data 6600 was the first machine I know of that did this kind of things. Integer addition took 300 nsec, memory reference (read or write) took 1000 nsec, multiplies and divides took a LOT longer. Up to around ten instructions could all be executing in parallel, depending on which functional units were required. The CDC 6600 FORTRAN compilers were VERY good at scheduling all of this.

share|improve this answer
    
In this case the input of the next instruction depends on the first instruction result, so it must be executed sequentially. –  SK-logic Jan 5 '12 at 17:15
    
@SK-logic: Not quite. The input of the second line depends on the result of the right-hand-side of the first line, but, based solely on what we can see in the original example code, it may NOT depend on the store to memory of the result of the first line. If x had been declared volatile (in C/C++), then the compiler would be required to store the result first, AND THEN RELOAD IT FROM MEMORY, before starting to compute the new value of y, since the "volatile" means that something (an interrupt handler, say) could come in and zap x between the two lines. –  John R. Strohm Jan 5 '12 at 22:17
    
I assumed x and y are registers (and the code is in a 3-address pseudoassembly language rather than something like C). In this case both instructions are unavoidably sequential. Otherwise OP had to ask two or more different questions instead of this one. –  SK-logic Jan 6 '12 at 7:24

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.