Computer Hardware and Embedded Systems Lecture 8
Hello, dear friend, you can consult us at any time if you have any questions, add WeChat: daixieit
Computing for Engineers
Lecture 8
Computer Hardware and Embedded Systems
1.What is a computer?
1.1. Structure of a computer
In Computer Science there are precise definitions of what a computer actually is. In this lecture we consider a computer to be any device which consists of the following components, and which is capable of executing instructions defined by a programmer:
Memory |
Input |
Central processing unit (CPU) |
Memory – stores the program (instructions), and data
CPU – carries out these instructions
Input/Output – communication with the outside world
The definition of a computer is very broad. It includes all desktop and laptop computers, mobile phones and tablets, but it also includes any devices which have been developed to perform any specialised function.
For example, the following systems all have specialised computers inside them, which perform one or more specialised functions:
Microwave oven
Washing machine
Cash machine
Heating / lighting systems
Engine control / monitoring
Medical devices
If a computer has been developed for a specialised purpose like these, it is usually called an embedded system or an embedded computer.
1.2. Additional components within a computer
CPU |
Memory |
Clock |
Clock – this is a high frequency square wave which is an alternating pulse of zeros and ones. These usually operate at GHz frequencies for desktop and laptops, and at MHz frequencies for embedded computers.
The clock is required by all units inside a computer to ensure that all their
operations are synchronised.
The clock is not to be confused with a separate component which records the actual time of day –such a component is normally called a “real-time clock” or a “BIOS clock”.
Bus – a bus is a collection of wires which connects any two components, such as the memory and the CPU. If a bus mainly carries data, it is the data bus and if it carries memory addresses, then it is the address bus.
There may also be buses to allow a computer to interface with the outside world. On many embedded systems this is often called the GPIO bus (General Purpose Input Output bus).
In many industries, there are specific bus standards which are used so that a developer can design an embedded system which can interface to other components. Examples include the Fieldbus and CAN Bus standards.
2. Bits and bytes
2.1. What are bits and bytes?
The fundamental unit of information in computing is a bit.
A bit indicates the presence of a high or low voltage on a bus. High-voltage values are given the bit value of ‘1’, low-voltage values have a bit value of ‘0’.
On most computers, the most common unit method of grouping bits is into bytes. Unless specifically stated, one byte can be assumed to contain eight bits.
Here is a diagram of a byte, together with the values of each bit for ints and chars:
128 64 32 16 8 4 2 1
The byte values are always written in this order, with the highest bit value on the left, and the lowest bit value ‘1’ on the right.
The left-hand (highest) bit value is called the Most Significant Bit (MSB) or Bit 7.
The right-hand (lowest) bit value is called the Least Significant Bit (LSB) or Bit 0.
For example, if we have a binary value of “1000 1011”, we insert the ones and zeros into the above byte, and add up the column values. “1000 1011” has a decimal value of 128 + 8 + 2 + 1 = 139.
Using the above byte, the lowest value we can represent is 0 and the largest value is 255, but we cannot represent negative values. In the C language we can declare unsigned variables which use this approach to store positive numbers only.
If we want to represent negative numbers, we can declare and use signed variables. Here the MSB has a negative bit value, all the other bits are unchanged:
64 32 16 8 4 2 1
“1000 1011” in a signed 8-bit byte would be equal to -128 + 8 + 2 + 1 which is a decimal value of -117.
The minimum value that can be represented in an signed 8-bit byte is -128, and the maximum value is +127.
Other definitions:
KB |
Kilobytes |
1024 bytes |
2 bytes or 10 bytes |
MB |
Megabytes |
1024*1024 bytes |
2 bytes or 10 bytes |
GB |
Gigabytes |
1024*1024*1024 bytes |
2 bytes or 10 bytes |
TB |
Terabytes |
1024*1024*1024 *1024 bytes |
2 bytes or 10 bytes |
2.2. Hexadecimal
As the display and typing in of long binary numbers is very long and prone to
errors, programmers frequently use the hexadecimal system to enter and display values:
4096 256 16 1
In each column, we enter 0-9 to represent themselves, and A to F to represent the decimal numbers from 10 to 15.
For example, “002E” in hexadecimal represents 2 x 16 + 14 which is the decimal number 30. You will not be asked in the exam to convert hexadecimal numbers to and from binary or decimal, but you could be asked to convert 8- bit binary values to and from decimal.
In the C language, printf and scanf both use the format “%x” to enter or display hexadecimal values.
Hexadecimal constants in the C language are prefixed using the “0x” characters:
int q = 0x102; /* Initialise q to a hex value of 102 (decimal value 258) */ |
3. Memory
3.1. What is memory?
As discussed earlier, the memory is the set of components inside a computer that are used to store instructions and data.
Each memory location has a unique location which is known as an address, and has one or more bytes of storage for each address location. In this lecture course, the data stored at each address will be referred to as the contents of that memory location.
Address |
Data / Contents |
0 |
11011011 |
1 |
11110001 |
2 |
10001001 |
. |
|
. |
|
1022 |
|
1023 |
|
On most computers, each memory location can store a single 8-bit byte. Since datatypes in C are usually longer than a single byte, this means that to store a single int (32 bits or four bytes) we need four memory locations.
Fortunately, the C language does this automatically, and this issue only needs to be considered further by the programmer in advanced scenarios, using different kinds of processor within a single system or application.
A group of bytes grouped together in this way is normally called a word. Words usually contain two, four or eight bytes depending on the computer type.
3.2. Memory Operators
In the C programming language we have the following memory operations:
The ‘&’ operator is the “address-of” operator. This takes any variable and returns the memory address at which that variable is stored.
The ‘*’ operator is the “contents-of” operator. This takes a memory
address and returns the contents at that memory location. We shall be using this idea in more detail in Lecture 9.
4. How are Datatypes stored inside a computer
We will first look at how the two floating point datatypes are stored, float and double.
Data type |
No. bits |
Range |
Typical no. of decimal places |
float |
32 bits |
+38 to -38 |
3 |
double |
64 bits |
+308 to -308 |
9 |
4.1. Floats
Floats are represented using a 32-bit internal format. This format is an international standard known as IEEE 754.
Sign |
Exponent |
Mantissa |
31 30 23 22 0
The sign indicates whether the float is positive or negative (there are no “unsigned” floats).
The exponent is a power of two, which is used to multiply the mantissa to represent the value being stored. This is all done automatically by the CPU and there is no extra work that needs to be done by the programmer.
4.2. Doubles
These are also specified by the IEEE 754 standard. The additional bits for the exponent enable much larger and smaller numbers to be stored (compared with the float), whilst the additional mantissa bits give the ability to store 9 decimal places instead of 3 which is the typical limit of the float.
Sign |
Exponent |
Mantissa |
63 62 51 50 0
The programmer should be aware that floats and doubles cannot be relied on to store exact values for any floating point value.
For example, if you write
double a = 5.0 + 3.0; double b = 16.0 / 2.0; |
Then it should be noted that because of the way floating point algorithms
work, a and b will typically not have exactly the same value. For example, a could have a value of 8.000000001 and b might have a value of 7.999999999.
Using the ‘==’ or ‘!=’ operator to check whether two floating point values are the same is therefore an unsafe operation because of this issue:
It is much better to check for small differences between two floating point values:
#define DIFF 1e-8
int main(void) { double a, b; . . if (fabs(a-b) < DIFF) /* If a and b are equal */ { . . } . } |
In the above program, two floating point values are regarded as equal if their difference is less than 10-8 . This is the only recommended way of checking whether two such values are equal to each other.
2022-01-17