Memory
CPU
Example
Naming
unit of addressing is a byte (8 bits)
every byte of memory has a unique addresss
some machines have 32-bit memory addresses, some have 64
Access
lots of things are too bit to fit in a single byte
CPU access memory in continguous, power of two size chunks of bytes.
# bytes | # bits | C | Java | Asm |
---|---|---|---|---|
1 | 8 | char | byte | byte |
2 | 16 | short | short | word |
4 | 32 | int | int | long |
8 | 64 | long | long | quad |
Sometimes we are interested in the integer value of chunk of bytes
Sometimes we are more interested in bits themselves, so we use base-2, binary
Once we used base-8, octal
Once we use base-16, hexadecimal
4-GB memory addresses go up to 3777777778 = ffffffff16
How many bits in a hexc "digit", a hexit?
Consider ONE hexit at a time:
6 a 5 5 0 e a 3
A byte is just 2 hexadecimal digits:
0x6a 0x55 0x0e 0xa3 => 0x6a550ea3
We use hex for addresses
Addition/subtraction in hex
Remember that:
First architectural decision:
Consider a 32-bit integer (int in Java or C)
What do each of these bytes represent?
We can start at the "big end"
Example, to store the number 0x12345678:
We can start at the "little end"
Example, to store the number 0x12345678:
What is an "aligned" address?
Aligned addresses are better:
CPU Implementation encourages alignment
CPU memory access looks liek:
This is translated by memory to:
So:
How is this simplified if:
21byte b = -6 // stored as 11111010
2int i = b; // stored as 11111111111111111111111111111010
Signed extension: used in signed data types
Zero extension: used in unsigned data types (C)
21int i = -6; // stored as 11111111111111111111111111111010
2byte b = i; // stored as stored as 11111010
What could go wrong?
What value would b get if i were 256? or 128?
Java warns you if you truncate implicity
To avoid warning, cast explicity:
byte b = (byte) i
a << b
: shift all bits in a
to the left b
times, fill remaining right bits with zero
a >> b
: shift all bits in a
to the right b
times
a
is unsigned, fill with zeros (zero-extend), otherwise fill with first bit of a (sign-extend)>>
sign-extends, operator >>>
zero-extends.a & b
: AND
applied to corresponding bits in a
and b
a | b
: OR
applied to corresponding bits in a
and b
a ^ b
: XOR
applied to corresponding bits in a
and b
~a
: inverts every bit of a
Shifting multiplies / divides by power of 2
a<<b
is equivalent to a>>b
is equivalent to Example: 22 in binary is 00010110
00001011
(22 shi ft right once, )00101100
(22 shifted left one, )01011000
(22 shifted left twice, )Works for negative numbers too, if using sign-extended shift
Review:
21byte b = -6; // stored as 11111010
2int i = b; // stored as 1111...1111 11111010
How can we get it to zero-extend instead of sign-extend?
Answer: using bit operations:
21// 0xFF in bits is: 0000…000011111111
2int u = b & 0xFF; // stored as 0000…000011111010