views:

351

answers:

11

I understand how code is compiled to assembly, and that assembly is a 1:1 replacement with binary codes. Can somebody help me understand how binary is connected to the hardware? How is the binary physically read and run? How does an if statement work in the hardware?

From google searches I'm thinking that maybe my question title should be "how is binary data put on a line of a bus" but I wasn't sure.

Thanks

A: 

(Vastly simplified)

The binary (say a string of binary from a line of machine code/asm) is loaded into memory from say disk. Then an instruction is sent by the processor logic to memory controller to load the contents of the memory into a processor local resister. It then gets interpreted as an instruction to do by the processor.

I learned this level of stuff by doing microcoding at college.

In reality there are many more steps that could occur, depending on the processor complexity and power. The processor is made up of various parts (ALU, registers etc) and they cooperate in getting instructions, data and processing. If you are interested in this level of understand and I commend you for asking the question, Id say get a book on computer architecture. I used Structure Computer Organisation by Tanenbaum at college.

Preet Sangha
Thank you, but i'm looking for unsimplified now :)
Nona Urbiz
Then is very much depends on the processor architecture.
Preet Sangha
A: 

Essentially, and very broadly speaking, the instructions end up in memory, and the program counter (PC) register holds the address of the first instruction.

The processor supports instructions that load can move data to/from memory to registers. The processor moves data into the instruction register, and that instruction gets executed at the next clock tick.

I'm not qualified to explain the electrical engineering behind that, but you could probably look it up.

Of course, this all fairly simplified, as there is a huge amount of parallelism going on in modern processors, and I don't even pretend to grok that in any meaningful way.

timdev
A: 

You may find this link of interest: http://www.eskimo.com/~ddf/Theory/Micro_Fund/Commands/AssyLnge.html

In a short explanation, typically the application will be loaded to some area in memory and the processor will be given the start address, for the main or starting part.

A processor can do two things, it can manipulate data and move data, so it will use special parts on the microprocessor called registers in order to store values or location that it will need.

So, for an if statement, there is a command for whether two values are equal and where to go if they are not (branch if not equal). There will be some others, such as branch of equal or branch of greater than.

These will be in the assembly.

The commands are put into registers, with the appropriate arguments and it will be calculated on the next clock cycle.

This is very simplified, but to a large extent, what you see in assembly is what the microprocessor will see.

To go into more detail would probably be out of scope for StackOverflow.

James Black
+5  A: 

A complete answer to your question would encompass a book, and a fairly thick one at that.

When you say "code" I'm assuming you're referring to a high level compiled language, like C++. Usually, a compiler translates this code into machine language, or binary as you state in your question. We'll neatly avoid all discussion of managed vs. unmanaged code, p-code, etc. That is, we're just talking about compilers that target specific processors/operating systems. Java, for example, compiles into a pseudo-code called bytecode. We're also going to avoid the whole matter of link editing, or linking, which is how multiple source modules get compiled into machine language then bound together into a single executable program.

Okay, now that we've covered most of what we're not going to cover, here's what usually happens. And by "usually", I mean most compiled languages in a DOS, Linux or Windows environment. The source code is translated into machine language, which is written out to an executable file. This executable file contains, more or less, an image of what the program should look like in memory. When you tell the operating system to run your program, the OS's equivalent of a "Load and Go" executes. What that means is that the memory image in the executable file is loaded into memory, then the operating system does a machine language JUMP to the first instruction in the program. The CPU then blindly follows the instructions from thereon, until an EXIT is encountered.

This whole JUMP... EXIT nastiness is a drastic oversimplification for modern OS's. As you can imagine, if the CPU were to follow, with blind obedience, the instructions in a program that's gone astray, the computer would crash... or worse. Such was the fate of many an errant program in the early days, and a prime contributor to many a BSOD.

Bob Kaufman
At 965 pages, a thick book indeed. =)
Crashworks
+1  A: 

This is a huge, very complicated topic. The best textbook I've seen on the subject is Patterson/Hennesy's "Computer Organization and Design", which has many editions.

Other than suggesting you read it, I wouldn't dare try to cram a semester-long class into a 500-character answer box.

Crashworks
A: 

This seems like a 'how do computers work' question but you're not likely to be satisfied by the answers you get from Google.

The details of how binary is 'connected' to the hardware is really the subject of computer design at a basic level. Some knowledge of hardware design is very useful for programmers, but not strictly necessary.

The answers, so far, are 'Vastly simplified' because, well, they have to be.

In general the explanations will only make sense to someone who understands the subject. I don't think there's much we can do about that.

EDIT: perhaps the best we can say is that the bits in binary numbers (the zeroes and ones) correspond directly to the circuits in the hardware because circuits can be configured to 'store' a bit value, and those bits can be manipulated by the circuitry.

That is, they can be stored, counted, added (and all the other basic arithmetic functions), output and input in groups forming whole numbers.

Briefly, the bits in the binary numbers correspond to the transistors in the hardware. This, as the others have said, is an enormous simplification. It frequently takes more than one transistor to handle a bit, but that depends on the cleverness of the hardware designer.

pavium
A: 

I dont see this as huge and complicated, the closer to the hardware the simpler it gets.

Write a disassembler, thats how the hardware does it. Most processors include the opcodes or instruction set in the same manual as the assembler language.

Look at the opcode for say an add instruction using registers, a few of the bits determine the source register, a few bits for destination register a few bits say that this is an add instruction. Let's say this instruction set you are looking at uses only two registers for a register based add. There is some logic, an adder, that can add two items the size of registers and output a result and a carry bit. Registers are stored on chip in memory bits sometimes called flip flops. So when an add is decoded the input registers are tied to the add logic using electronic switches. These days this happens at the beginning of the clock cycle, by the end of the clock cycle the adder has a result and the output is routed to the bits for the destination register and the answer is captured. Normally an add will modify the flags in the flag register. When the result is too big to be stored in the register (think about what happens when you add the decimal numbers 9 and 1 you get a 0 carry the 1 right?). There is some logic that looks at the output of the adder and compares the bits with the value zero that sets or clears the z flag in the flag register. Another flag bit is the sign bit or n bit for negative, that is the most significant bit of the answer. This is all done in parallel.

Then say your next instruction is jump if zero (jump if equal), the logic looks at the z flag. If set then the next instruction fetched is based on bits in the instruction that are added to the program counter through the same or another adder. Or perhaps the bits in the instruction point to an address in memory that hold the new value for the program counter. Or maybe the condition is false, then the program counter is still run through an adder but what is added to it is the size of the instruction so that it fetches the next instruction.

The stretch from a disassembler to a simulator is not a long one. You make variables for each of the registers, decode the instructions, execute the instructions, continue. Memory is an array you read from or write to. The disassembler is your decode step. The simulator performs the same steps as the hardware, the hardware just does it in parallel using different programming tricks and different programming languages.

Depending on how implemented your disassembler might start at the beginning of the program and disassemble to the end, your simulator would start at the beginning but follow the code execution which is not necessarily beginning to end.

Old game console simulators like MAME have processor simulators that you can look at. Unfortunately, esp with MAME, the code is designed for execution speed not readability and most are completely unreadable. There are some readable simulators out there if you look though.

A friend pointed me at this book http://www1.idc.ac.il/tecs/ which I would like to read, but have not yet. Perhaps it is just the book you are looking for.

Sure hardware has evolved from trivial state machines that take many clocks to fetch, decode, and execute serially. My guess is that if you just understood the classic fetch, decode and execute that is enough for this question. Then you may have other more specific questions, or perhaps I misunderstood the question and you really wanted to understand the memory bus and not the decoder.

dwelch
That book link leads to a video describing a full-blown stack based vm with very complete alu, all from scratch-0 instruction fetch / decode.
Nicholas Jordan
+1  A: 

There is a Book named code which goes over that as well as any computer organization text. Thogh the answers here are all good.

Recursion
Phil Devaney
A: 

In a very simplified way the computer can be represented as an infinite loop (implemented in hardware) and abilities to do simple arithmetic operations (also implemented in hardware). In the loop it does the following:

  • read the memory at PC (PC is the loop counter which gets incremented)
  • decode the command and operands
  • execute the command
  • write the results back to memory

And that's it. Also there are control commands which can change the PC and which are used for "if ... then ... else" statement.

grigy
A: 

This question is very complicated, I have 2 degrees in exactly that and I've still only scratched the surface.

If you want an intro to how that all works together, MIT has some free classes available you can look over online. This one is probably the best one to get you started.

Jeff Shattock
A: 

I think this is actually a fun question. I would say "here's how to build a computer in a few easy steps".

  • Start with some simple logic circuits, such as AND, OR, NOT, and a flip-flop. A flip-flop is a pair of transistors arranged so that if one is ON, the other is OFF, or vice-versa. That way it can "remember" one bit of information, so you can think of it as a storing a single binary digit. Some input lines can put it in one state or the other, and thus "write" to it.

  • You can store a bigger number by having a bunch of flip-flops, and call it a "register". For example, if you have four flip-flops in a register, there are 16 possible combinations, so you can think of it as holding a number from 0 to 15.

  • Skipping ahead a little bit, you can buy a "memory chip". What that is is a good number of registers, like say 16 of them. It has 4 wires coming in (the "address" wires), and it has 4 wires coming out (the "data" wires). So a number from 0 to 15 can come in as an address, and that selects one of the 16 registers, whose value is presented on the output data wires (thus "reading" it). Another few wires can cause data to come IN on the data wires to cause numbers to be put into ("written") the register.

  • Now suppose you have an external 4-bit register (call it R), and a bit of circuitry, so that it 1) presents the value in R to the memory address, 2) reads the 4-bit value at that register and moves it into R, then repeats over and over.

Depending on the numbers that have been pre-loaded into the memory, you can see that this thing will cycle around through a series of numeric addresses, because the number at each address determines what the next address will be.

Now, you can embellish this thing in a lot of ways. You can expand the memory to have 5-bits of address (32 registers). Then if one of the address lines is connected to the outside world, it will do different things depending on the outside world. That's a "finite-state-machine".

You can replace the R register with a simple counter, and call it a "program counter". You can take the data coming out of the memory and call it an "instruction", and use some of its bits to read other memory addresses and load a set of arithmetic registers. You can use some to control whether the R register simply increments, or maybe gets a new address stored in it. That's called "jumping".

Of course, this is a very simple computer, but that's roughly how they started out.

Mike Dunlavey