Version without JavaScript, read-only: workshops, quizzes and running code are not available here. Full version · Catalogue · Sign in
Lecture notes · chapter 1
Representing information
Everything the processor handles is a sequence of bits. How we write numbers in it, positive or negative, characters, and how we store them in memory.
Bits and bases
The bit, the byte
A computer knows only two states: 0 and 1. That is the bit. Bits are grouped by 8 into a byte, which can take 2⁸ = 256 different values. The 68000 handles three sizes, given by a suffix in its instructions:
| Size | Suffix | Bits | Different values |
|---|---|---|---|
| byte | .B | 8 | 256 |
| word | .W | 16 | 65,536 |
| long word (long) | .L | 32 | a little over 4 billion |
Three ways to write a number
The same number can be written in several bases. In 68000 assembly, a prefix says which one:
| Base | Prefix | Example | Digits |
|---|---|---|---|
| decimal (10) | none | 45 | 0 to 9 |
| binary (2) | % | %00101101 | 0 and 1 |
| hexadecimal (16) | $ | $2D | 0 to 9, then A (10) to F (15) |
These three notations denote the same number, forty-five.
From binary to decimal: each digit is worth a power of 2, from right to left 1, 2, 4, 8, 16… %00101101 = 32 + 8 + 4 + 1 = 45.
From decimal to binary: divide by 2 as long as you can, and read the remainders from bottom to top. 45 = 2 × 22 + 1; 22 = 2 × 11 + 0; 11 = 2 × 5 + 1; 5 = 2 × 2 + 1; 2 = 2 × 1 + 0; 1 = 2 × 0 + 1. We read %101101.
Between binary and hexadecimal, it is immediate: one hexadecimal digit is exactly 4 bits. Cut the binary number into groups of 4 from the right: %0010 1101 gives 2 and D, that is $2D. That is why almost everything is written in hexadecimal: it is binary, four times shorter.
Negative numbers
Two's complement
On 8 bits, we can encode the integers from 0 to 255. To encode negative numbers as well, the 68000, like almost every processor, uses two's complement: on $n$ bits, we encode the integers from −2ⁿ⁻¹ to 2ⁿ⁻¹ − 1, that is from −128 to 127 on a byte.
To get the encoding of −x from that of x:
- invert all the bits;
- add 1.
The leftmost bit, called the most significant bit, gives the sign: 0 for a positive number or zero, 1 for a negative number.
Same bits, two readings
The processor does not know whether a byte is signed or not: the programmer decides how to read it. $FF is 255 read as unsigned, and −1 read in two's complement. $80 is 128, or −128.
| Byte | Unsigned | Two's complement |
|---|---|---|
$00 | 0 | 0 |
$7F | 127 | 127 |
$80 | 128 | −128 |
$FF | 255 | −1 |
Sign extension
To turn a signed number from a byte into a word, copy its sign bit to the left. −10 is written $F6 on 8 bits and $FFF6 on 16 bits; 118 is written $76 and $0076. Padding with zeros would be a mistake: $00F6 is 246.
Carry and overflow
When two numbers are added, the result may not fit in the chosen size. There are two ways to fail, depending on the reading:
- unsigned, the result exceeds the largest value: there is a carry;
- signed, the result leaves the range, for instance the sum of two positive numbers looks negative: there is an overflow.
Memory
A big array of bytes
Memory is an array of bytes, each one identified by a number, its address, written in hexadecimal: $1000, $1001… A word takes two consecutive bytes, a long word four.
Big-endian: most significant byte first
To store a long word, we must choose in which order to write its four bytes. The 68000 is big-endian: the most significant byte is at the lowest address. The long word $12345678 stored at address $2000 gives:
| Address | $2000 | $2001 | $2002 | $2003 |
|---|---|---|---|---|
| Byte | $12 | $34 | $56 | $78 |
You read memory in the order you write the number. (Intel processors do the opposite: they are little-endian.)
Alignment
On the 68000, a word or a long word must start at an even address. Reading a word at address $2001 causes an address error, which stops the program. A byte, on the other hand, can be at any address.
Characters
A character is stored in a byte, according to the ASCII code: 'A' is $41 (65), 'B' is $42, 'a' is $61, the digit '0' is $30, the space $20. A character string is a sequence of bytes in memory, and its end is often marked by a null byte, $00.
Two useful consequences:
- you go from an uppercase letter to the lowercase one by adding
$20; - you get the value of a digit by subtracting
$30from its code:'7'−'0'=$37−$30= 7.