Tools needed:
1.
PC running Windows Operating
System (OS)
2.
DevC++ (installed)
1. Memory
Storage:
In computer programming, information is stored in
a computer memory with different data types. We must know what is to be stored
in a computer memory, whether it is a simple number, a letter or a very large
number. As we also know, computer memory is organized in bytes, and for these
variables with varying information a data type is associated. The minimum
amount of memory in computer memory is a byte that can store a small amount of
data and managed easily. Every variable is declared with two entities, its type
and its name. There are several data types available in C++. The basic built in
data types are char, int, float, double and bool.
1.1.
Primitive Data Types in C++:
C++ offers the programmer a rich assortment of
built-in as well as user defined data types. Following table lists down seven
basic C++ data types:
Several of the basic types can be modified using
one or more of these type modifiers:
·
Signed
·
Unsigned
·
Short
·
long
The
following table shows the variable type, how much memory it takes to store the
value in memory, and what is maximum and minimum value which can be stored in
such type of variables.
Figure 1. Table showing memory requirements of Data types
Note: The
sizes of variables might be different from those shown in the above table,
depending on the compiler and the computer you are using.
2. Storing Signed/Unsigned Integers
It is imperative that you feel comfortable with binary and hexadecimal
conversion. Following sections cover a few basic concepts.
2.1.
Binary and Hexadecimal Conversion
Conversion between binary and hexadecimal notation is straightforward.
To convert a binary number, divide it into groups of four bits starting from
least significant bit. Add additional zeros to the most significant bit to make
the total number of bits a multiple of four. Hexadecimal (or hex) notation is
convenient because it saves space. Notice, any number starting with 0x is a hex
value.
Dec
|
Bin
|
Hex
|
|
|
|
0
|
0b0000
|
0x0
|
1
|
0b0001
|
0x1
|
2
|
0b0010
|
0x2
|
3
|
0b0011
|
0x3
|
4
|
0b0100
|
0x4
|
5
|
0b0101
|
0x5
|
6
|
0b0110
|
0x6
|
7
|
0b0111
|
0x7
|
8
|
0b1000
|
0x8
|
9
|
0b1001
|
0x9
|
10
|
0b1010
|
0xA
|
11
|
0b1011
|
0xB
|
12
|
0b1100
|
0xC
|
13
|
0b1101
|
0xD
|
14
|
0b1110
|
0xE
|
15
|
0b1111
|
0xF
|
Table
2. 4-bit Binary-Hexadecimal Conversion
2.2.
Storing Unsigned Integers in Memory
Storing
unsigned integers is simple and the procedure is outlined as:
1.
Convert the decimal
number to its equivalent binary form.
2.
Add 0's before the
most significant bit to fill up 32 bits
3.
Divide number
into 4 bytes. LSB corresponds to 1st byte and so on.
4.
Lower bytes go to low
memory addresses and higher bytes go to high memory addresses.
2.2.1 Example
Suppose we want to store an unsigned integer with
value 27 at address 0x00000010.
27
|
=
|
1
|
1
|
0
|
1
|
1
|
=
|
000000000
|
00000000
|
00000000
|
00011011
|
|
|
MSB
|
|
|
LSB
|
||||||
|
Byte No.
|
1
|
2
|
3
|
4
|
Memory Map:
Address
|
Data (Bin)
|
Data (Hex)
|
Byte No
|
0x00000010
|
00011011
|
1B
|
1
|
0x00000011
|
00000000
|
00
|
2
|
0x00000012
|
00000000
|
00
|
3
|
0x00000013
|
00000000
|
00
|
4
|
2.2.2
2’sCompliment Notation
Signed data types like ‘int’ can have negative values. The negative
numbers are stored as 2's complement in memory. To calculate 2's complement of
a number invert all the bits and add a 1. For example, 0110 (6 in decimal) in
inverted form is 1001. By adding 1 we get 1010 which is the 2's complement of
0110. Therefore, -6 would be stored in memory as 1010.
3.
Memory Map in Dev C++
Look minutely at the code
below. Save it in lab_07.cpp.
#include
<iostream>
#include
<iomanip>
using
namespace std;
int main()
{
long long x= 1234;
int y= 1234;
cout << "x = " << "\t"
<< right << x << ", &x = " << &x;
cout << ", x (hex) = "
<< "\t" << right << hex << x << dec;
cout << endl;
cout << "y = " << "\t"
<< right << y << ", &y = " << &y;
cout << ", y (hex) = "
<< "\t" << right << hex << y << dec;
cout << endl;
return 0;
}
There are few new things to note about the code:
1.
Output stream manipulators
hex and dec: hex
manipulator shows the integer type variable in hexadecimal (base 16) and dec manipulator shows in decimal. There
is a third manipulator oct that can be used to output octal (base 8) equivalent
of the number.
2.
Operator & (read
'Address of'): Every variable occupies
space (bytes) in memory. These bytes are always contiguous (together in
sequence). Each byte has an address to identify it. The address of the first
byte (smallest in value) is considered to be the address of the variable.
Addresses
(by default) are printed in hexadecimal. So if, for example, the address of the
variable x is 4d2, then bytes with addresses 4d2, 4d3, 4d4, and 4d5 are the 4
bytes allocated to the variable x but the smallest of these addresses (or the
address of the first byte allocated) is said to be the address of x, i.e.,
address of x is 4d2.
Use
of & with any variable in a cout statement would show the address at which
that variable is stored.
Now run the code and note the output. A sample output
is shown as follows:
f = 1234, &f = 0x22fe3c, f (hex)
= 1234
x = 1234, &x = 0x22fe38, x (hex)
= 4d2
float has a size of 4 bytes. Its value is 1234. Its
address of 0x22fe3c shows that the first byte of 4 bytes allocated to it has
the address 22fe3c. The addresses of other 3 bytes would be 22fe3d, 22fe3e and
22fe3f.
The manipulator hex does not work with float data
types.
Similarly, the value of long variable x is 1234 and
its address is 22fe38. The value 1234 in decimal is equal to 0x4d2 in hex. Verify it.
The contents of the first byte of variable x of type
long would be d2, that of second byte would be 04, that of third byte would be
00 and of fourth would be 00 as well.
The full 32 bit value of variable x would be:
0000 0000 0000 0000 0000 0100 1101 0010
Byte contents of variable x:
Address
|
Contents in hex
|
Contents in
binary
|
22fe38
|
D2
|
1101 0010
|
22fe39
|
04
|
0000 0100
|
22fe40
|
00
|
0000 0000
|
22fe41
|
00
|
0000 0000
|
Task # 1:
Make
a calculator that gets two integer hexadecimal numbers from user and shows
their sum in hexadecimal. The output should be shown as addition sums are done
on paper, e.g. a sample output is shown below:
Enter 1st number
in hex: FF16
Enter 2nd number
in hex: ABC
FF16
+ ABC
------------
109D2
Note:
The
hex and oct manipulators work with input streams for integer data types as
well. Try this code to verify it.
int x;
cin
>> hex >> x; //provide FF as
input
cout
<< x; //the decimal equivalent of
hex value FF shown
Code:
#include <iostream>
#include<iomanip>
using namespace std;
int
main()
{
int
x;
int
n1, n2, sum;
cout
<< " Enter 1st number in hexadecimal : ";
cin
>>hex>> n1;
cout
<< " Enter 2nd number in
hexadecimal : ";
cin
>>hex>> n2;
sum=n1+n2;
cout
<<" "<<setw(5)<<hex<<n1<<endl;
cout<<
" + "<<setw(3)<<hex<<n2<< endl;
cout
<< "----------"<<endl;
cout
<< hex<<"
"<<sum<<endl;
cout
<< "----------"<<endl;
return
0;
}
Task
# 2:
Take
a random number, for example your roll number. On paper how would this number
be stored as an unsigned integer, unsigned short and unsigned long long in
memory in hex? Now modify code in lab_07.cpp file to print these values
on console. Does your paperwork match
the actual value shown on console?
Code:
#include <iostream>
#include <iomanip>
using namespace std;
int main()
{
unsigned long long x=1907;
unsigned int z=1907;
unsigned short y=1907;
cout << "
unsigned long long Roll Number = " << "\t" << right
<< x << ", &Roll Number = " << &x;
cout << ",
Roll Number (hex) = " << "\t" << right << hex
<< x << dec;
cout << endl;
cout << " unsigned short Roll Number = " <<
"\t" << right << y << ", &Roll Number =
" << &y;
cout << ",
Roll Number (hex) = " << "\t" << right << hex
<< y << dec;
cout << endl;
cout << "unsigned int Roll Number = " <<
"\t" << right << z << ", &Roll Number =
" << &z;
cout << ",
Roll Number (hex) = " << "\t" << right << hex
<< z << dec;
cout << endl;
return 0;
}
Output:
unsigned long long
Roll Number = 1907, &Roll
Number = 0x6ffe38, Roll Number (hex) =
773
unsigned short Roll Number = 1907, &Roll Number = 0x6ffe32, Roll
Number (hex) = 773
unsigned int Roll Number = 1907, &Roll Number = 0x6ffe34, Roll
Number (hex) = 773
Task # 3:
Repeat the previous exercise assuming the
number was negative.
#include <iostream>
#include <iomanip>
using namespace std;
int main()
{
long long
x=-1907;
int z=-1907;
short y=-1907;
cout << "
long long Roll Number = " << "\t" << right <<
x << ", &Roll Number = " << &x;
cout << ",
Roll Number (hex) = " << "\t" << right << hex
<< x << dec;
cout << endl;
cout << " short Roll
Number = " << "\t" << right << y <<
", &Roll Number = " << &y;
cout << ",
Roll Number (hex) = " << "\t" << right << hex
<< y << dec;
cout << endl;
cout << " int Roll Number = " << "\t"
<< right << z << ", &Roll Number = " <<
&z;
cout << ",
Roll Number (hex) = " << "\t" << right << hex
<< z << dec;
cout << endl;
return 0;
}
Output:
long long Roll
Number = -1907, &Roll Number =
0x6ffe38, Roll Number (hex) =
fffffffffffff88d
short Roll Number = -1907, &Roll Number = 0x6ffe32, Roll
Number (hex) = f88d
int
Roll Number = -1907, &Roll
Number = 0x6ffe34, Roll Number (hex) =
fffff88d
Task
# 4:
Experiment
with data types and values given below and report how do they store positive
and negative values, if they store numbers. Note your observations here and
show them (as well as your code) to the instructor.
bool b = true;
|
|
Address
|
Byte value in hex
|
0x6ffe3f
|
1
|
bool b = -10;
|
|
Address
|
Byte value in
hex
|
0x6ffe3f
|
1
|
bool b = 0;
|
|
Address
|
Byte value in
hex
|
0x6ffe3f
|
0
|
short s = ______19____;
//initialize with a value of your choice
|
|
Address
|
Byte value in
hex
|
0x6ffe3e
|
13
|
0x6ffe3f
|
00
|
short s = __-80_________;
//initialize with a negative value
|
|
Address
|
Byte value in
hex
|
0x6ffe3e
|
B0
|
0x6ffe3f
|
00
|
long long ll = __________32________________;
//initialize with a value of your choice
|
|
Address
|
Byte value in
hex
|
0x6ffe38
|
20
|
0x6ffe39
|
00
|
0x6ffe40
|
00
|
0x6ffe41
|
00
|
0x6ffe42
|
00
|
0x6ffe43
|
00
|
0x6ffe44
|
00
|
0x6ffe45
|
00
|
long long ll = ______________-32_________;
//initialize with a negative value
|
|
Address
|
Byte value in
hex
|
0x6ffe38
|
E0
|
0x6ffe39
|
ff
|
0x6ffe40
|
ff
|
0x6ffe41
|
ff
|
0x6ffe42
|
ff
|
0x6ffe43
|
ff
|
0x6ffe44
|
ff
|
0x6ffe45
|
ff
|
Observations:
Value is first stored in memory addresses accordig to
data type for instance long long uses 8 memory addresses and short uses 2 memory addresses.also that when negative
numbers are entered all the zero’s in memory addresses are replaced by F’s.
No comments:
Post a Comment