$\newcommand{\doubler}[1]{2#1} \newcommand{\binary}{\mathtt} \newcommand{\hex}{\mathtt} \newcommand{\octal}{\mathtt} \newcommand{\prog}{\mathtt} \newcommand{\lt}{<} \newcommand{\gt}{>} \newcommand{\amp}{&}$

Exercises2.2Exercises

Exercise1

1. $\hex{4567}$

2. $\hex{89ab}$

3. $\hex{fedc}$

4. $\hex{0252}$

Exercise2

1. $\binary{1000} \; \binary{0011} \; \binary{1010} \; \binary{1111}$

2. $\binary{1001} \; \binary{0000} \; \binary{0000} \; \binary{0001}$

3. $\binary{1010} \; \binary{1010} \; \binary{1010} \; \binary{1010}$

4. $\binary{0101} \; \binary{0101} \; \binary{0101} \; \binary{0101}$

Exercise3

1. $32$

2. $48$

3. $4$

4. $16$

Exercise4

1. $2$

2. $8$

3. $16$

4. $3$

5. $5$

6. $2$

Exercises2.4Exercises

Exercise1

Decimal number: $r = 10, n = 8, d_{7} = 2, d_{6} = 9, d_{5} = 4, d_{4} = 5, d_{3} = 8, d_{2} = 2, d_{1} = 5, d_{0} = 4$

Hexadecimal number: $r = 16, n = 8, d_{7} = 2, d_{6} = 9, d_{5} = 4, d_{4} = 5, d_{3} = 8, d_{2} = 2, d_{1} = 5, d_{0} = 4$

Exercise2

\begin{align*} \binary{1010} \; \binary{0101}_{2} &= 1 \times 2^{7} + 0 \times 2^{6} + 1 \times 2^{5} + 0 \times 2^{4} + 0 \times 2^{3} + 1 \times 2^{2} + 0 \times 2^{1} + 1 \times 2^{0}\\ &= 128 + 0 + 32 + 0 + 0 + 4 + 0 + 1 \\ &= 165_{10} \end{align*}
Exercise3

1. $170$

2. $85$

3. $240$

4. $15$

5. $128$

6. $99$

7. $123$

8. $255$

Exercise4

1. $43981$

2. $4660$

3. $65244$

4. $2015$

5. $32768$

6. $1024$

7. $32170$

8. $12345$

Exercise5

1. Set $Result = 0$

2. For $i = 0, \cdots, (n-1)$

• $Result = Result + d_{i} * 16^{i}$

1. $40960$

2. $65535$

3. $1024$

4. $4369$

5. $34952$

6. $400$

7. $43981$

8. $21845$

Exercises2.6Exercises

Exercise1

$\binary{1111011} = \hex{7d}$

Exercise2

1. $\hex{64}$

2. $\hex{7d}$

3. $\hex{0a}$

4. $\hex{58}$

5. $\hex{ff}$

6. $\hex{10}$

7. $\hex{20}$

8. $\hex{80}$

Exercise3

1. $\hex{0400}$

2. $\hex{03e8}$

3. $\hex{8000}$

4. $\hex{7fff}$

5. $\hex{0100}$

6. $\hex{ffff}$

7. $\hex{1234}$

8. $\hex{abcd}$

Exercise4

Since there are 12 values, we need 4 bits. Any 4-bit code would work. Here is one example:

 Grade Code (in hex) A $\binary{0000}$ $\hex{0}$ A- $\binary{0001}$ $\hex{1}$ B+ $\binary{0010}$ $\hex{2}$ B $\binary{0011}$ $\hex{3}$ B- $\binary{0100}$ $\hex{4}$ C+ $\binary{0101}$ $\hex{5}$ C $\binary{0110}$ $\hex{6}$ C- $\binary{0111}$ $\hex{7}$ D+ $\binary{1000}$ $\hex{8}$ D $\binary{1001}$ $\hex{9}$ D- $\binary{1010}$ $\hex{a}$ F $\binary{1011}$ $\hex{b}$

Exercises2.8Exercises

Exercise1

Four bytes are sufficient to store an unsigned integer up to $4,294,967,295$ so we would need to allocate the memory bytes at $\hex{2fffeb96}\text{,}$ $\hex{2fffeb97}\text{,}$ $\hex{2fffeb98}\text{,}$ and $\hex{2fffeb99}\text{.}$

Exercise2
 $\hex{00100e}\text{:}$ $\hex{00}$ $\hex{00100f}\text{:}$ $\hex{01}$ $\hex{001010}\text{:}$ $\hex{02}$ $\hex{001011}\text{:}$ $\hex{03}$ $\cdots$ $\cdots$ $\hex{00102a}\text{:}$ $\hex{1c}$ $\hex{00102b}\text{:}$ $\hex{1d}$
Exercise3

$\hex{10}_{16}\text{,}$ which is 0x10 in C/C++ syntax.

Exercises2.10Programming Exercises

Exercise2

You can type as many $\hex{f}$s as you like, but the program only accepts eight. Therefore, the largest unsigned integer is $4 \times 8 = 32$ bits.

Exercise3
Solution
printf("%#010x represents the unsigned decimal integer %d\n",
bitPattern, bitPattern);


Any integer greater than $\hex{7fffffff}$ gives a negative output. This will be explained in Section 3.4, but for now realize that this change is caused by printf formatting, not the storage format, which is still unsigned int. Also note that we did not change scanf's reading format.

Exercise4
Solution
/* echoDecHexAddr.c
* Prompts user to enter a number in decimal, another in
* hexadecimal then echoes both in both bases, also showing
* where values are stored.
* 2017-09-29: Bob Plantz
*/

#include <stdio.h>

int main(void)
{
int x;
unsigned int y;

while(1)           // loop "forever"
{
printf("Enter a decimal integer (0 to quit): ");
scanf("%i", &x);
if (x == 0) break;        // break out of loop

printf("Enter a bit pattern in hexadecimal: ");
scanf("%x", &y);
if (y == 0) break;        // break out of loop

printf("%i is stored as %#010x at %p, and\n", x, x, &x);
printf("%#010x represents the decimal integer %d stored at %p\n\n",
y, y, &y);
}
printf("End of program.\n");

return 0;
}


Notice the use of an “infinite” loop and a break statement to end a program.

Exercises2.14Programming Exercise

Exercise1
Solution
/* stringInHex.c
* displays each character in "Hello world" in hex
* and the address where it is stored.
*
* 2017-09-29: Bob Plantz
*/

#include <stdio.h>

int main(void)
{
char *stringPtr = "Hello world.\n";

while (*stringPtr != '\0')
{
printf("%p:  ", stringPtr);
printf("0x%02x\n", *stringPtr);
stringPtr++;
}
printf("%p:  ", stringPtr);
printf("0x%02x\n", *stringPtr);

return 0;
}


Exercises2.16Programming Exercises

Exercise1
Solution
/* echoString1.c
* Echoes a string entered by user.
* 2017-09-29: Bob Plantz
*/

#include <unistd.h>
#include <string.h>

int main(void)
{
char aString[200];
char *stringPtr = aString;

write(STDOUT_FILENO, "Enter a text string: ",
strlen("Enter a text string: "));  // prompt user

read(STDIN_FILENO, stringPtr, 1);    // get first character
while (*stringPtr != '\n')           // look for end of line
{
stringPtr++;                       // move to next location
read(STDIN_FILENO, stringPtr, 1);  // get next character
}

// now echo for user
write(STDOUT_FILENO, "You entered:\n",
strlen("You entered:\n"));
stringPtr = aString;
do
{
write(STDOUT_FILENO, stringPtr, 1);
stringPtr++;
} while (*stringPtr != '\n');
write(STDOUT_FILENO, stringPtr, 1);

return 0;
}

Exercise2
Solution
/* echoString2.c
* Echoes a string entered by user. Converts input
* to C-style string.
* 2017-09-29: Bob Plantz
*/

#include <stdio.h>
#include <unistd.h>
#include <string.h>

int main(void)
{
char aString[200];
char *stringPtr = aString;

write(STDOUT_FILENO, "Enter a text string: ",
strlen("Enter a text string: ")); // prompt user

read(STDIN_FILENO, stringPtr, 1);    // get first character
while (*stringPtr != '\n')           // look for end of line
{
stringPtr++;                       // move to next location
read(STDIN_FILENO, stringPtr, 1);  // get next character
}
*stringPtr = '\0';                   // make into C string

// now echo for user
printf("You entered:\n%s\n", aString);

return 0;
}

Exercise3
Solution

There are five separate files for this solution. Four of the files, writeStr.h, writeStr.c, readLn.h, and readLn.c, will be used with other programs in the book. If you do not know how to compile multiple-file programs in C, refer to Appendix A.

/* echoString3.c
* Echoes a string entered by user.
* 2017-09-29: Bob Plantz
*/

#include "writeStr.h"
#define STRLEN 5     // limited to 5 for testing readStr
// change to 200 for use

int main(void)
{
char aString[STRLEN];
writeStr("Enter a text string: ");
writeStr("You entered:\n");
writeStr(aString);
writeStr("\n");

return 0;
}

/* writeStr.h
* Writes a line to standard out.
*
* input:
*    pointer to C-style text string
* output:
*    to screen
*    returns number of chars written
*
* 2017-09-29: Bob Plantz
*/

#ifndef WRITESTR_H
#define WRITESTR_H
int writeStr(char *);
#endif

/* writeStr.c
* Writes a line to standard out.
*
* input:
*    pointer to C-style text string
* output:
*    to screen
*    returns number of chars written
*
* 2017-09-29: Bob Plantz
*/

#include <unistd.h>
#include "writeStr.h"

{
int count = 0;

{
count++;
}

return count;
}

/* readLn.h
* Reads a line from standard in.
* Drops newline character. Eliminates
* excess characters from input buffer.
*
* input:
*    from keyboard
* output:
*    null-terminated text string
*    returns number of chars in text string
*
* 2017-09-29: Bob Plantz
*/

#endif

/* readLn.c
* Reads a line from standard in.
* Drops newline character. Eliminates
* excess characters from input buffer.
*
* input:
*    from keyboard
* output:
*    null-terminated text string
*    returns number of chars in text string
*
* 2017-09-29: Bob Plantz
*/

#include <unistd.h>

{
int count = 0;
maxLength--;          // allow space for NUL
{
if (count < maxLength)
{
count++;
}
}
*stringAddr = '\0';   // terminate C string

return count;
}


Exercises3.2Exercises

Exercise1

Four bits. Note that six of the bit patterns are unused.

Exercise2
Solution

• $carry_{0} = 0$

• For $i = 0, \cdots, (N-1)$

• sum$_{i} = (x_{i} + y_{i} + carry_{i})$ % $2$

• carry$_{i+1} = (x_{i} + y_{i} + carry_{i}) / 2$

Exercise3
Solution

• $carry_{0} = 0$

• For $i = 0, \cdots, (N-1)$

• sum$_{i} = (x_{i} + y_{i} + carry_{i})$ % $16$

• carry$_{i+1} = (x_{i} + y_{i} + carry_{i}) / 16$

Exercise4
Solution

Using the bit patterns in Table 3.1.3, we could store one decimal digit in every four bits. That is, the lowest-order digit would be stored in bits 3–0, the next lower-order digit in bits 7–4, etc. For example, let's consider $48 + 27\text{:}$

 $48_{10}$ $\rightarrow$ $\hex{00000048}_{16}$ + $27_{10}$ $\rightarrow$ $\hex{00000027}_{16}$ $75_{10}$ $\ne$ $\hex{0000007f}_{16}$

Exercise5
Solution

Subtracting $y$ from $x\text{.}$

• $borrow = 0$

• For $i = 0, \cdots, (N-1)$

• If $y_{i} \le x_{i}$

• difference$_{i} = x_{i} - y_{i}$

• Else

• $j = i + 1$

• While $(x_{j} = 0)$ and $(j \lt N)$

• $j = j + 1$

• If $j = N$

• $borrow = 1$

• $j = j - 1$

• $x_{j} = x_{j} + 2$

• While $j \gt i$

• $x_{j} = x_{j} - 1$

• $j = j - 1$

• $x_{j} = x_{j} + 2$

• difference$_{i} = x_{i} - y_{i}$

Exercise6
Solution

Subtracting $y$ from $x\text{.}$

• $borrow = 0$

• For $i = 0, \cdots, (N-1)$

• If $y_{i} \le x_{i}$

• difference$_{i} = x_{i} - y_{i}$

• Else

• $j = i + 1$

• While $(x_{j} = 0)$ and $(j \lt N)$

• $j = j + 1$

• If $j = N$

• $borrow = 1$

• $j = j - 1$

• $x_{j} = x_{j} + 16$

• While $j \gt i$

• $x_{j} = x_{j} - 1$

• $j = j - 1$

• $x_{j} = x_{j} + 16$

• difference$_{i} = x_{i} - y_{i}$

Exercises3.5Exercises

Exercise1
Solution

• If $x \ge 0$

• Convert $x$ to binary.

• Else

• Negate $x$

• Convert the result to binary.

• Compute the 2's complement of the result in the binary domain.

Exercise2
Solution

• If high-oder bit is $0$

• Convert $x$ to decimal.

• Else

• Compute the 2's complement of $x\text{.}$

• Compute the decimal equivalent of the result.

Exercise3

1. $+85$

2. $-85$

3. $-16$

4. $+15$

5. $-128$

6. $+99$

7. $+123$

Exercise4

1. $+4660$

2. $-30875$

3. $+22136$

4. $-4660$

5. $-292$

6. $+2016$

7. $-32768$

8. $+32767$

9. $-32767$

Exercise5

1. $\hex{64}$

2. $\hex{ff}$

3. $\hex{f6}$

4. $\hex{58}$

5. $\hex{81}$

6. $\hex{f0}$

7. $\hex{e0}$

8. $\hex{80}$

Exercise6

1. $\hex{7bcd}$

2. $\hex{ff04}$

3. $\hex{0400}$

4. $\hex{fc00}$

5. $\hex{ffff}$

6. $\hex{8000}$

7. $\hex{7fff}$

8. $\hex{ff00}$

9. $\hex{8001}$

10. $\hex{ff80}$

Exercises3.7Exercises

Exercise1

1. Start at the tic mark for $1\text{,}$ move $3$ tic marks CW, giving $4 = \binary{100}_{2}\text{.}$ We did not pass the tic mark at the top, so C = $\binary{0}\text{,}$ and the result is correct.

2. Start at the tic mark for $3\text{,}$ move $4$ tic marks CW, giving $7 = \binary{111}_{2}\text{.}$ We did not pass the tic mark at the top, so C = $\binary{0}\text{,}$ and the result is correct.

3. Start at the tic mark for $5\text{,}$ move $6$ tic marks CW, giving $3 = \binary{011}_{2}\text{.}$ We passed the tic mark at the top, so C = $\binary{1}\text{,}$ and the result is wrong.

4. Start at the tic mark for $+1\text{,}$ move $3$ tic marks CW, giving $-4 = \binary{100}_{2}\text{.}$ We passed the tic mark at the bottom, so V = $\binary{1}\text{,}$ and the result is wrong.

5. Start at the tic mark for $-3\text{,}$ move $3$ tic marks CCW, giving $+2 = \binary{010}_{2}\text{.}$ We passed the tic mark at the bottom, so C = $\binary{0}\text{,}$ and the result is wrong.

6. Start at the tic mark for $+3\text{,}$ move $4$ tic marks CCW, giving $-1 = \binary{111}_{2}\text{.}$ We did not pass the tic mark at the bottom, so C = $\binary{0}\text{,}$ and the result is correct.

Exercise2
 sum signed unsigned a. $\hex{ff}$ right right b. $\hex{45}$ right wrong c. $\hex{fb}$ right right
 sum signed unsigned d. $\hex{de}$ wrong right e. $\hex{0e}$ right wrong f. $\hex{00}$ wrong wrong
Exercise3
 sum signed unsigned a. $\hex{0000}$ right wrong b. $\hex{1110}$ right wrong c. $\hex{0000}$ wrong wrong
 sum signed unsigned d. $\hex{03ff}$ right wrong e. $\hex{7fff}$ right right f. $\hex{7fff}$ wrong wrong

Exercises4.3Programming Exercise

Exercise1

Shifting $17$ to the left $14$ times gives $278528\text{.}$ Shifting $17$ to the right $3$ times gives $2\text{.}$

Exercises4.5Programming Exercise

Exercise1
Solution
/* convertHex.c
* then echoes it in hexadecimal and in decimal.
* Assumes that user does not make mistakes.
* 2017-09-29: Bob Plantz
*/

#include <stdio.h>
#include <unistd.h>

int main(void)
{
int x;
unsigned char aChar;

printf("Enter an integer in hexadecimal: ");
fflush(stdout);

x = 0;                          // initialize result
read(STDIN_FILENO, &aChar, 1);  // get first character
while (aChar != '\n') {        // look for return key
x = x << 4;                   // make room for next four bits
if (aChar > '9') {
aChar = aChar + 9;          // for 'gap' in hex
}
aChar = aChar & 0x0f;         // mask off ascii part
x = x + (int)aChar;           // insert in vacant space
}

printf("You entered %#010x = %d (decimal)\n\n", x, x);

return 0;
}


The fflush(stdout); statement is required because output to stdout is line buffered.

Exercises5.2Exercises

Exercise1
Solution

For Equation (5.1.3):

 $x$ $x \cdot 1$ $\binary{0}$ $\binary{0}$ $\binary{1}$ $\binary{1}$

And for Equation (5.1.4):

 $x$ $x + 0$ $\binary{0}$ $\binary{0}$ $\binary{1}$ $\binary{1}$
Exercise2
Solution

For Equation (5.1.5):

 $x$ $y$ $x \cdot y$ $y \cdot x$ $\binary{0}$ $\binary{0}$ $\binary{0}$ $\binary{0}$ $\binary{0}$ $\binary{1}$ $\binary{0}$ $\binary{0}$ $\binary{1}$ $\binary{0}$ $\binary{0}$ $\binary{0}$ $\binary{1}$ $\binary{1}$ $\binary{1}$ $\binary{1}$

And for Equation (5.1.6):

 $x$ $y$ $x + y$ $y + x$ $\binary{0}$ $\binary{0}$ $\binary{0}$ $\binary{0}$ $\binary{0}$ $\binary{1}$ $\binary{1}$ $\binary{1}$ $\binary{1}$ $\binary{0}$ $\binary{1}$ $\binary{1}$ $\binary{1}$ $\binary{1}$ $\binary{1}$ $\binary{1}$
Exercise3
Solution

For Equation (5.1.7):

 $x$ $x \cdot 0$ $\binary{0}$ $\binary{0}$ $\binary{1}$ $\binary{0}$

And for Equation (5.1.8):

 $x$ $x + 1$ $\binary{0}$ $\binary{1}$ $\binary{1}$ $\binary{1}$
Exercise4
Solution

For Equation (5.1.9):

 $x$ $x'$ $x \cdot x'$ $\binary{0}$ $\binary{1}$ $\binary{0}$ $\binary{1}$ $\binary{0}$ $\binary{0}$

And for Equation (5.1.10):

 $x$ $x'$ $x + x'$ $\binary{0}$ $\binary{1}$ $\binary{1}$ $\binary{1}$ $\binary{0}$ $\binary{1}$
Exercise5
Solution
 $x$ $x$ $x \cdot x$ $\binary{0}$ $\binary{0}$ $\binary{0}$ $\binary{1}$ $\binary{1}$ $\binary{1}$

And for Equation (5.1.12):

 $x$ $x$ $x + x$ $\binary{0}$ $\binary{0}$ $\binary{0}$ $\binary{1}$ $\binary{1}$ $\binary{1}$
Exercise6
Solution
 $x$ $y$ $z$ $y + z$ $x \cdot (y + z)$ $x \cdot y$ $x \cdot z$ $x \cdot y + x \cdot z$ $\binary{0}$ $\binary{0}$ $\binary{0}$ $\binary{0}$ $\binary{0}$ $\binary{0}$ $\binary{0}$ $\binary{0}$ $\binary{0}$ $\binary{0}$ $\binary{1}$ $\binary{1}$ $\binary{0}$ $\binary{0}$ $\binary{0}$ $\binary{0}$ $\binary{0}$ $\binary{1}$ $\binary{0}$ $\binary{1}$ $\binary{0}$ $\binary{0}$ $\binary{0}$ $\binary{0}$ $\binary{0}$ $\binary{1}$ $\binary{1}$ $\binary{1}$ $\binary{0}$ $\binary{0}$ $\binary{0}$ $\binary{0}$ $\binary{1}$ $\binary{0}$ $\binary{0}$ $\binary{0}$ $\binary{0}$ $\binary{0}$ $\binary{0}$ $\binary{0}$ $\binary{1}$ $\binary{0}$ $\binary{1}$ $\binary{1}$ $\binary{1}$ $\binary{0}$ $\binary{1}$ $\binary{1}$ $\binary{1}$ $\binary{1}$ $\binary{0}$ $\binary{1}$ $\binary{1}$ $\binary{1}$ $\binary{0}$ $\binary{1}$ $\binary{1}$ $\binary{1}$ $\binary{1}$ $\binary{1}$ $\binary{1}$ $\binary{1}$ $\binary{1}$ $\binary{1}$

And for Equation (5.1.14):

 $x$ $y$ $z$ $y \cdot z$ $x + y \cdot z$ $x + y$ $x + z$ $(x + y) \cdot (x + z)$ $\binary{0}$ $\binary{0}$ $\binary{0}$ $\binary{0}$ $\binary{0}$ $\binary{0}$ $\binary{0}$ $\binary{0}$ $\binary{0}$ $\binary{0}$ $\binary{1}$ $\binary{0}$ $\binary{0}$ $\binary{0}$ $\binary{1}$ $\binary{0}$ $\binary{0}$ $\binary{1}$ $\binary{0}$ $\binary{0}$ $\binary{0}$ $\binary{1}$ $\binary{0}$ $\binary{0}$ $\binary{0}$ $\binary{1}$ $\binary{1}$ $\binary{1}$ $\binary{1}$ $\binary{1}$ $\binary{1}$ $\binary{1}$ $\binary{1}$ $\binary{0}$ $\binary{0}$ $\binary{0}$ $\binary{1}$ $\binary{1}$ $\binary{1}$ $\binary{1}$ $\binary{1}$ $\binary{0}$ $\binary{1}$ $\binary{0}$ $\binary{1}$ $\binary{1}$ $\binary{1}$ $\binary{1}$ $\binary{1}$ $\binary{1}$ $\binary{0}$ $\binary{0}$ $\binary{1}$ $\binary{1}$ $\binary{1}$ $\binary{1}$ $\binary{1}$ $\binary{1}$ $\binary{1}$ $\binary{1}$ $\binary{1}$ $\binary{1}$ $\binary{1}$ $\binary{1}$

Exercises5.4Exercise

Exercise1
Solution

The $\sum$ column shows where the sum of minterms evaluates to $1\text{,}$ and the $\prod$ column shows where the product of maxterms evaluates to $0\text{.}$ Of course, in the blank cells the functions evaluate to the complementary value.

 $x$ $y$ $z$ $F(x,y,z) = \sum(0,1,5,6)$ $F(x,y,z) = \prod(2,3,4,7)$ $\binary{0}$ $\binary{0}$ $\binary{0}$ $\binary{1}$ $\binary{0}$ $\binary{0}$ $\binary{1}$ $\binary{1}$ $\binary{0}$ $\binary{1}$ $\binary{0}$ $\binary{0}$ $\binary{0}$ $\binary{1}$ $\binary{1}$ $\binary{0}$ $\binary{1}$ $\binary{0}$ $\binary{0}$ $\binary{0}$ $\binary{1}$ $\binary{0}$ $\binary{1}$ $\binary{1}$ $\binary{1}$ $\binary{1}$ $\binary{0}$ $\binary{1}$ $\binary{1}$ $\binary{1}$ $\binary{1}$ $\binary{0}$

Exercises5.6Exercises

Exercise1
Solution

Let a 4-bit integer be $wxyz$ where each literal represents one bit. The even 4-bit integers are given by the function:

\begin{alignat*}{1} F(w,x,y,z) \amp {}={} w' \cdot x' \cdot y' \cdot z' + w' \cdot x' \cdot y \cdot z' + w' \cdot x \cdot y' \cdot z' + w' \cdot x \cdot y \cdot z' \\ \amp \quad + w \cdot x' \cdot y' \cdot z' + w \cdot x' \cdot y \cdot z' + w \cdot x \cdot y' \cdot z' + w \cdot x \cdot y \cdot z' \end{alignat*}

Using the distributive property repeatedly we get:

\begin{alignat*}{1} F(w,x,y,z) \amp {}={} z' \cdot (w' \cdot x' \cdot y' + w' \cdot x' \cdot y + w' \cdot x \cdot y' + w' \cdot x \cdot y \\ \amp \quad + w \cdot x' \cdot y' + w \cdot x' \cdot y + w \cdot x \cdot y' + w \cdot x \cdot y) \\ \amp {}={} z' \cdot (w' \cdot (x' \cdot y' + x' \cdot y + x \cdot y' + x \cdot y) \\ \amp \quad + w \cdot (x' \cdot y' + x' \cdot y + x \cdot y' + x \cdot y)) \\ \amp {}={} z' \cdot (w' + w) \cdot (x' \cdot y' + x' \cdot y + x \cdot y' + x \cdot y) \\ \amp {}={} z' \cdot (w'+ w) \cdot (x' \cdot (y' + y) + x \cdot (y' + y)) \\ \amp {}={} z' \cdot (w' + w) \cdot (x' + x) \cdot (y' + y) \end{alignat*}

And from the complement property we arrive at a minimal sum of products:

\begin{gather*} F(w,x,y,z) = z' \end{gather*}

which you recognize as Figure 5.1.3.

Exercise2
Solution

First we draw the Karnaugh map:

Several groupings are possible. Keep in mind that groupings can wrap around. We will work with:

which yields a minimal sum of products:

\begin{equation*} F(x,y,z) = z' + x' \cdot y' + x \cdot y \end{equation*}
Exercise3
Solution

This expression includes maxterms 0, 1, 3, 4, and 7. These appear in a Karnaugh map:

Next we encircle the largest adjacent blocks, where the number of cells in each block is a power of two. Notice that maxterm $M_{0}$ appears in two groups.

From this Karnaugh map it is very easy to write the function as a minimal product of sums:

\begin{equation*} F(x,y,z) = (x + y) \cdot (y + z) \cdot (y' + z') \end{equation*}
Exercise4
Solution

Using the Karnaugh map zeros:

we obtain the complement of our desired function:

\begin{equation*} F'(x,y,z) = x' \cdot y \cdot z + x \cdot y' \cdot z \end{equation*}

and from DeMorgan's Law:

\begin{equation*} F(x,y,z) = (x + y' + z') \cdot (x' + y + z') \end{equation*}
Exercise7
Solution

The prime numbers correspond to the minterms $m_{2}\text{,}$ $m_{3}\text{,}$ $m_{5}\text{,}$ and $m_{7}\text{.}$ The minterms $m_{10}\text{,}$ $m_{11}\text{,}$ $m_{12}\text{,}$ $m_{13}\text{,}$ $m_{14}\text{,}$ $m_{15}$ cannot occur so are marked “don't care” on the Karnaugh map.

which gives:

\begin{equation*} F(w,x,y,z) = x \cdot z + x' \cdot y \end{equation*}

Exercises6.4Exercise

Exercise1
Solution
 $x_1$ $x_0$ $y_1$ $y_0$ $F(x,y)$ $0$ $0$ $0$ $0$ $0$ $0$ $0$ $0$ $1$ $1$ $0$ $0$ $1$ $0$ $1$ $0$ $0$ $1$ $1$ $1$ $0$ $1$ $0$ $0$ $0$ $0$ $1$ $0$ $1$ $0$ $0$ $1$ $1$ $0$ $1$ $0$ $1$ $1$ $1$ $1$ $1$ $0$ $0$ $0$ $0$ $1$ $0$ $0$ $1$ $0$ $1$ $0$ $1$ $0$ $0$ $1$ $0$ $1$ $1$ $1$ $1$ $1$ $0$ $0$ $0$ $1$ $1$ $0$ $1$ $0$ $1$ $1$ $1$ $0$ $0$ $1$ $1$ $1$ $1$ $0$

Exercises8.6Programming Exercises

Exercise1

This can vary, depending on different versions of the compiler, etc. This is an exercise on using gdb so you can become comfortable with it for when you will actually need it to find your errors. It is also an excellent learning tool.

Exercise2

The contents of the register should be one less than the integer you entered when the program prompted you. The C statement uses 12 bytes of program memory.

Exercise3

The program uses the address of ex, &ex, so the variable must be located in memory.

Exercise5
Solution
/* endian.c
* Determines endianess. If endianess cannot be determined
* from input value, defaults to "big endian"
* 2017-09-29: Bob Plantz
*/

#include <stdio.h>

int main(void)
{
unsigned char *ptr;
int x, i, bigEndian;

ptr = (unsigned char *)&x;

printf("Enter a non-zero integer: ");
scanf("%i", &x);

printf("You entered %#010x and it is stored\n", x);
for (i = 0; i < 4; i++)
printf("   %p: %02x\n", ptr + i, *(ptr + i));

bigEndian = (*ptr == (unsigned char)(0xff & (x >> 24))) &&
(*(ptr + 1) == (unsigned char)(0xff & (x >> 16))) &&
(*(ptr + 2) == (unsigned char)(0xff & (x >> 8))) &&
(*(ptr + 3) == (unsigned char)(0xff & x));
if (bigEndian)
printf("which is big endian.\n");
else
printf("which is little endian.\n");

return 0;
}

Exercise6
Solution
/* endianReg.c
* Stores user int in memory then copies to register var.
* Use gdb to observe endianess.
* 2017-09-29: Bob Plantz
*/

#include <stdio.h>

int main(void)
{
int x;
register int y;

printf("Enter an integer: ");
scanf("%i", &x);

y = x;
printf("You entered %i\n", y);

return 0;
}


Exercises9.4Programming Exercises

Exercise1

The exit code is displayed in octal.

Exercise2
Solution
@ f.s
@ Does nothing but return zero to caller.
@ 2017-09-29: Bob Plantz

@ Define my Raspberry Pi
.cpu    cortex-a53
.fpu    neon-fp-armv8
.syntax unified         @ modern syntax

@ Program code
.text
.align  2
.global f
.type   f, %function
f:
str     fp, [sp, -4]!   @ save caller frame pointer
add     fp, sp, 0       @ establish our frame pointer

mov     r0, 0           @ return values go in r0

sub     sp, fp, 0	      @ delete allocated memory
ldr     fp, [sp], 4     @ restore caller's frame pointer
bx      lr              @ back to caller

Exercise3
Solution
@ g.s
@ Returns 123 to caller.
@ 2017-09-29: Bob Plantz

@ Define my Raspberry Pi
.cpu    cortex-a53
.fpu    neon-fp-armv8
.syntax unified         @ modern syntax

@ Program code
.text
.align  2
.global g
.type   g, %function
g:
str     fp, [sp, -4]!   @ save caller frame pointer
add     fp, sp, 0       @ establish our frame pointer

mov     r0, 123         @ return values go in r0

sub     sp, fp, 0	      @ delete allocated memory
ldr     fp, [sp], 4     @ restore caller's frame pointer
bx      lr              @ back to caller

Exercise4
Solution
/* checkRetNos.c
* calls three assembly language functions and
* prints their return numbers.
*
* 2017-09-29: Bob Plantz
*/

#include <stdio.h>
int positiveNumber(void);
int negativeNumber(void);
int maxNumber(void);

int main()
{
int x;

x = positiveNumber();
printf("Here is a positive constant: %i, ", x);

x = negativeNumber();
printf("a negative constant: %i, ", x);

x = maxNumber();
printf("and the maximum number: %i.\n", x);

return 0;
}

@ positiveNumber.s
@ Returns +100 to caller.
@ 2017-09-29: Bob Plantz

@ Define my Raspberry Pi
.cpu    cortex-a53
.fpu    neon-fp-armv8
.syntax unified         @ modern syntax

@ Program code
.text
.align  2
.global positiveNumber
.type   positiveNumber, %function
positiveNumber:
str     fp, [sp, -4]!   @ save caller frame pointer
add     fp, sp, 0       @ establish our frame pointer

mov     r0, 100         @ return +100

sub     sp, fp, 0	      @ restore stack pointer
ldr     fp, [sp], 4     @ restore caller's frame pointer
bx      lr              @ back to caller

@ negativeNumber.s
@ Returns -100 to caller.
@ 2017-09-29: Bob Plantz

@ Define my Raspberry Pi
.cpu    cortex-a53
.fpu    neon-fp-armv8
.syntax unified         @ modern syntax

@ Program code
.text
.align  2
.global negativeNumber
.type   negativeNumber, %function
negativeNumber:
str     fp, [sp, -4]!   @ save caller frame pointer
add     fp, sp, 0       @ establish our frame pointer

mov     r0, -100        @ return -100

sub     sp, fp, 0	      @ restore stack pointer
ldr     fp, [sp], 4     @ restore caller's frame pointer
bx      lr              @ back to caller

@ maxNumber.s
@ Returns the largest "immediate data" constant to caller,
@ which is 8 bits.
@ 2017-09-29: Bob Plantz

@ Define my Raspberry Pi
.cpu    cortex-a53
.fpu    neon-fp-armv8
.syntax unified         @ modern syntax

@ Program code
.text
.align  2
.global maxNumber
.type   maxNumber, %function
maxNumber:
str     fp, [sp, -4]!   @ save caller frame pointer
add     fp, sp, 0       @ establish our frame pointer

mov     r0, 0xff        @ only 8 bits available for immediate

sub     sp, fp, 0	      @ restore stack pointer
ldr     fp, [sp], 4     @ restore caller's frame pointer
bx      lr              @ back to caller

Exercise5
Solution
/*
* checkRetChars.c
* calls three assembly language functions and
* prints their return characters.
*
* 2017-09-29: Bob Plantz
*/

#include <stdio.h>
int A(void);
int z(void);
int hashtag(void);

int main()
{
char aCharacter;

aCharacter = A();
printf("Here some characters: %c, ", aCharacter);

aCharacter = z();
printf("%c, ", aCharacter);

aCharacter = hashtag();
printf("and %c.\n", aCharacter);

return 0;
}

@ A.s
@ Returns 'A' to caller.
@ 2017-09-29: Bob Plantz

@ Define my Raspberry Pi
.cpu    cortex-a53
.fpu    neon-fp-armv8
.syntax unified         @ modern syntax

@ Program code
.text
.align  2
.global A
.type   A, %function
A:
str     fp, [sp, -4]!   @ save caller frame pointer
add     fp, sp, 0       @ establish our frame pointer

mov     r0, 'A          @ return 'A'

sub     sp, fp, 0	      @ restore stack pointer
ldr     fp, [sp], 4     @ restore caller's frame pointer
bx      lr              @ back to caller

@ z.s
@ Returns 'z' to caller.
@ 2017-09-29: Bob Plantz

@ Define my Raspberry Pi
.cpu    cortex-a53
.fpu    neon-fp-armv8
.syntax unified         @ modern syntax

@ Program code
.text
.align  2
.global z
.type   z, %function
z:
str     fp, [sp, -4]!   @ save caller frame pointer
add     fp, sp, 0       @ establish our frame pointer

mov     r0, 'z          @ return 'z'

sub     sp, fp, 0	      @ restore stack pointer
ldr     fp, [sp], 4     @ restore caller's frame pointer
bx      lr              @ back to caller

@ hashtag.s
@ Returns '#' to caller.
@ 2017-09-29: Bob Plantz

@ Define my Raspberry Pi
.cpu    cortex-a53
.fpu    neon-fp-armv8
.syntax unified         @ modern syntax

@ Program code
.text
.align  2
.global hashtag
.type   hashtag, %function
hashtag:
str     fp, [sp, -4]!   @ save caller frame pointer
add     fp, sp, 0       @ establish our frame pointer

mov     r0, #'#         @ return hashtag

sub     sp, fp, 0	      @ restore stack pointer
ldr     fp, [sp], 4     @ restore caller's frame pointer
bx      lr              @ back to caller


Exercises10.4Programming Exercise

Exercise1
Solution
@ helloBob.s
@ Hello Bob program, in assembly language.
@ 2017-09-29: Bob Plantz

@ Define my Raspberry Pi
.cpu    cortex-a53
.fpu    neon-fp-armv8
.syntax unified         @ modern syntax

@ Useful source code constant
.equ    STDOUT,1

@ Constant program data
.section  .rodata
.align  2
helloMsg:
.asciz	 "Hello, Bob!\n"
.equ    helloLngth,.-helloMsg

@ Program code
.text
.align  2
.global main
.type   main, %function
main:
sub     sp, sp, 8       @ space for fp, lr
str     fp, [sp, 0]     @ save fp
str     lr, [sp, 4]     @   and lr
add     fp, sp, 4       @ set our frame pointer

mov     r0, STDOUT      @ file number to write to
ldr     r1, helloMsgAddr   @ pointer to message
mov     r2, helloLngth  @ number of bytes to write
bl      write           @ write the message

mov     r0, 0           @ return 0;
ldr     fp, [sp, 0]     @ restore caller fp
ldr     lr, [sp, 4]     @       lr
add     sp, sp, 8       @   and sp
bx      lr              @ return

.align  2
.word   helloMsg


Exercises10.6Programming Exercise

Exercise1
Solution

Experiment with entering different numbers of characters, and you will see that the read function reads the newline character (enter key) as one character. Try entering “abcdls” (without the quotes). Notice that any characters beyond the four requested remain in the input buffer and are read by the shell when the program exits.

@ echo4chars.s
@ Prompts user to enter 4 characters and echoes them
@ 2017-09-29: Bob Plantz

@ Define my Raspberry Pi
.cpu    cortex-a53
.fpu    neon-fp-armv8
.syntax unified         @ modern syntax

@ Useful source code constants
.equ    STDIN,0
.equ    STDOUT,1
.equ    char1,-8
.equ    char2,-7
.equ    char3,-6
.equ    char4,-5
.equ    nChars,4
.equ    local,8

@ Constant program data
.section  .rodata
.align  2
promptMsg:
.asciz  "Enter four characters: "
.equ    promptLngth,.-promptMsg
responseMsg:
.asciz	"You entered: "
.equ    responseLngth,.-responseMsg

@ Program code
.text
.align  2
.global main
.type   main, %function
main:
sub     sp, sp, 8       @ space for fp, lr
str     fp, [sp, 0]     @ save fp
str     lr, [sp, 4]     @   and lr
add     fp, sp, 4       @ set our frame pointer
sub     sp, sp, local   @ allocate memory for local var

mov     r0, STDOUT      @ prompt user for input
mov     r2, promptLngth
bl      write

mov     r0, STDIN       @ from keyboard
mov     r2, 1           @ one char

mov     r0, STDIN       @ from keyboard
mov     r2, 1           @ one char

mov     r0, STDIN       @ from keyboard
mov     r2, 1           @ one char

mov     r0, STDIN       @ from keyboard
mov     r2, 1           @ one char

mov     r0, STDOUT      @ nice message for user
mov     r2, responseLngth
bl      write

mov     r0, STDOUT      @ echo user's characters
mov     r2, nChars      @ all four characters
bl      write

mov     r0, 0           @ return 0;
add     sp, sp, local   @ delete local vars
ldr     fp, [sp, 0]     @ restore caller fp
ldr     lr, [sp, 4]     @       lr
add     sp, sp, 8       @   and sp
bx      lr              @ return

.align  2
.word   promptMsg
.word   responseMsg


Exercises12.2Programming Exercises

Exercise1
Solution
@ numerals.s
@ Displays the numerals, 0 - 9
@ 2017-09-29: Bob Plantz

@ Define my Raspberry Pi
.cpu    cortex-a53
.fpu    neon-fp-armv8
.syntax unified         @ modern syntax

@ Useful source code constants
.equ    STDOUT,1
.equ    numeral,-20
.equ    local,8

@ Constant program data
.section .rodata
.align  2
@ The program
.text
.align  2
.global main
.type   main, %function
main:
sub     sp, sp, 16      @ space for saving regs
@ (keeping 8-byte sp align)
str     r4, [sp, 4]     @ save r4
str     fp, [sp, 8]     @      fp
str     lr, [sp, 12]    @      lr
add     fp, sp, 12      @ set our frame pointer
sub     sp, sp, local   @ allocate memory for local var

mov     r4, '0          @ numeral 0
loop:
strb    r4, [fp, numeral]  @ char must be
@ in memory for write
mov     r0, STDOUT      @ write to screen
mov     r2, 1           @ one byte
bl      write

add     r4, r4, 1       @ next numeral
cmp     r4, '9          @ all numerals?
ble     loop            @ no, keep going

mov     r0, 0           @ yes, return 0;
add     sp, sp, local   @ deallocate local var
ldr     r4, [sp, 4]     @ restore r4
ldr     fp, [sp, 8]     @         fp
ldr     lr, [sp, 12]    @         lr
add     sp, sp, 16      @         sp
bx      lr              @ return

Exercise2
Solution
@ letters.s
@ Displays the upper case alphabet, A - Z
@ 2017-09-29: Bob Plantz

@ Define my Raspberry Pi
.cpu    cortex-a53
.fpu    neon-fp-armv8
.syntax unified         @ modern syntax

@ Useful source code constants
.equ    STDOUT,1
.equ    alpha,-20
.equ    local,8

@ Constant program data
.section .rodata
.align  2
@ The program
.text
.align  2
.global main
.type   main, %function
main:
sub     sp, sp, 16      @ space for saving regs
@ (keeping 8-byte sp align)
str     r4, [sp, 4]     @ save r4
str     fp, [sp, 8]     @      fp
str     lr, [sp, 12]    @      lr
add     fp, sp, 12      @ set our frame pointer
sub     sp, sp, local   @ allocate memory for local var

mov     r4, 'A          @ beginning of alphabet
loop:
strb    r4, [fp, alpha] @ char must be
@ in memory for write
mov     r0, STDOUT      @ write to screen
mov     r2, 1           @ one byte
bl      write

add     r4, r4, 1       @ next alpha
cmp     r4, 'Z          @ whole alphabet?
ble     loop            @ no, keep going

mov     r0, 0           @ yes, return 0;
add     sp, sp, local   @ deallocate local var
ldr     r4, [sp, 4]     @ restore r4
ldr     fp, [sp, 8]     @         fp
ldr     lr, [sp, 12]    @         lr
add     sp, sp, 16      @         sp
bx      lr              @ return


Exercises12.4Programming Exercise

Exercise1
Solution
@ range3.s
@ Checks if user entered a numeral
@ 2017-09-29: Bob Plantz

@ Define my Raspberry Pi
.cpu    cortex-a53
.fpu    neon-fp-armv8
.syntax unified         @ modern syntax

@ Useful source code constants
.equ    STDOUT,1
.equ    STDIN,0
.equ    NUL,0
.equ    response,-20
.equ    local,8

@ Constant program data
.section .rodata
.align  2
prompt:
.asciz  "Enter a single character: "
.align  2
numeral:
.asciz  "You entered a numeral.\n"
.align  2
other:
.asciz  "You entered a non-numeric character.\n"

@ The program
.text
.align  2
.global main
.type   main, %function
main:
sub     sp, sp, 16      @ space for saving regs
@ (keeping 8-byte sp align)
str     r4, [sp, 4]     @ save r4
str     fp, [sp, 8]     @      fp
str     lr, [sp, 12]    @      lr
add     fp, sp, 12      @ set our frame pointer
sub     sp, sp, local   @ local variable

ldr     r4, promptAddr  @ prompt user
promptLoop:
ldrb    r3, [r4]        @ get a char
cmp     r3, NUL         @ end of string?
beq     getResponse     @ yes, get response

mov     r0, STDOUT      @ no, write to screen
mov     r1, r4          @ address of current char
mov     r2, 1           @ write 1 byte
bl      write

add     r4, r4, 1       @ increment pointer var

getResponse:
mov     r0, STDIN       @ from keyboard
mov     r2, 2           @ one char plus enter key

ldrb    r3, [fp, response] @ load response
cmp     r3, '9          @ check high end
bhi     notNumeral      @ >'9', other char
cmp     r3, '0          @ check low end
blo     notNumeral      @ <'0', other char

ldr     r4, numeralAddr @ "You entered a numeral."
numLoop:
ldrb    r3, [r4]        @ get a char
cmp     r3, NUL         @ end of string?
beq     endThen         @ yes, end of then block
mov     r0, STDOUT      @ no, write to screen
mov     r1, r4          @ address of current char
mov     r2, 1           @ write 1 byte
bl      write
add     r4, r4, 1       @ increment pointer var
endThen:
b       endElse         @ branch over else block

notNumeral:
ldr     r4, otherAddr   @ "You entered some other character."
notNumLoop:
ldrb    r3, [r4]        @ get a char
cmp     r3, NUL         @ end of string?
beq     endElse         @ yes, end of if-else
mov     r0, STDOUT      @ no, write to screen
mov     r1, r4          @ address of current char
mov     r2, 1          @ write 1 byte
bl      write
add     r4, r4, 1       @ increment pointer var

endElse:
mov     r0, 0           @ return 0;
add     sp, sp, local   @ deallocate local var
ldr     r4, [sp, 4]     @ restore r4
ldr     fp, [sp, 8]     @         fp
ldr     lr, [sp, 12]    @         lr
add     sp, sp, 16      @         sp
bx      lr              @ return

.align        2
.word   prompt
.word   numeral
.word   other


Exercises13.3Programming Exercises

Exercise1
Solution

I suggest discussing this with your instructor and colleagues. Opinions will differ. Listen and learn.

Exercise2
Solution
@ writeStr.s
@ Writes a C-style text string to the standard output (screen).
@ Calling sequence:
@       r0 <- address of string to be written
@       bl    writestr
@ returns number of characters written
@ 2017-09-29: Bob Plantz

@ Define my Raspberry Pi
.cpu    cortex-a53
.fpu    neon-fp-armv8
.syntax unified         @ modern syntax

@ Useful source code constants
.equ    STDOUT,1
.equ    NUL,0

@ The code
.text
.align  2
.global writeStr
.type   writeStr, %function
writeStr:
sub     sp, sp, 16      @ space for saving regs
str     r4, [sp, 0]     @ save r4
str     r5, [sp, 4]     @      r5
str     fp, [sp, 8]     @      fp
str     lr, [sp, 12]    @      lr
add     fp, sp, 12      @ set our frame pointer

mov     r4, r0          @ r4 = string pointer
mov     r5, 0           @ r5 = count
whileLoop:
ldrb    r3, [r4]        @ get a char
cmp     r3, NUL         @ end of string?
beq     allDone         @ yes, all done

mov     r0, STDOUT      @ no, write to screen
mov     r1, r4          @ address of current char
mov     r2, 1           @ write 1 byte
bl      write

add     r4, r4, 1       @ increment pointer var
add     r5, r5, 1       @ count++
allDone:
mov     r0, r5          @ return count;
ldr     r4, [sp, 0]     @ restore r4
ldr     r5, [sp, 4]     @      r5
ldr     fp, [sp, 8]     @         fp
ldr     lr, [sp, 12]    @         lr
add     sp, sp, 16      @ restore sp
bx      lr              @ return

@ helloWorld3.s
@ Hello world program to test writeStr function
@ 2017-09-29: Bob Plantz

@ Define my Raspberry Pi
.cpu    cortex-a53
.fpu    neon-fp-armv8
.syntax unified         @ modern syntax

@ Constant program data
.section .rodata
.align   2
theString:
.asciz        "Hello World.\n"

@ The program
.text
.align  2
.global main
.type   main, %function
main:
sub     sp, sp, 8       @ space for fp, lr
str     fp, [sp, 0]     @ save fp
str     lr, [sp, 4]     @   and lr
add     fp, sp, 4       @ set our frame pointer

bl      writeStr

mov     r0, 0           @ return 0;
ldr     fp, [sp, 0]     @ restore caller fp
ldr     lr, [sp, 4]     @       lr
add     sp, sp, 8       @   and sp
bx      lr              @ return

.word    theString

Exercise3
Solution
@ readLnSimple.s
@ Reads a line (through the '\n') from standard input. Deletes
@ the '\n' and creates a C-style text string.
@ Calling sequence:
@       r0 <- address of place to store string
@ returns number of characters read, excluding NUL.
@ 2017-09-29: Bob Plantz

@ Define my Raspberry Pi
.cpu    cortex-a53
.fpu    neon-fp-armv8
.syntax unified         @ modern syntax

@ Useful source code constants
.equ    STDIN,0
.equ    NUL,0
.equ    LF,10     @ '\n' under Linux

@ The code
.text
.align  2
sub     sp, sp, 16      @ space for saving regs
str     r4, [sp, 4]     @ save r4
str     r5, [sp, 8]     @      r5
str     fp, [sp, 12]    @      fp
str     lr, [sp, 16]    @      lr
add     fp, sp, 12      @ set our frame pointer

mov     r4, r0          @ r4 = string pointer
mov     r5, 0           @ r5 = count

mov     r0, STDIN       @ read from keyboard
mov     r1, r4          @ address of current storage
mov     r2, 1           @ read 1 byte
whileLoop:
ldrb    r3, [r4]        @ get just read char
cmp     r3, LF          @ end of input?
beq     endOfString     @ yes, input done
add     r4, r4, 1       @ no, increment pointer var
add     r5, r5, 1       @ count++
mov     r0, STDIN       @ read from keyboard
mov     r1, r4          @ address of current storage
mov     r2, #1          @ read 1 byte
b       whileLoop       @ and check for end
endOfString:
mov     r0, NUL         @ string terminator
strb    r0, [r4]        @ write over '\n'

mov     r0, r5          @ return count;
ldr     r4, [sp, 4]     @ restore r4
ldr     r5, [sp, 8]     @      r5
ldr     fp, [sp, 12]    @      fp
ldr     lr, [sp, 16]    @      lr
add     sp, sp, 16      @ space for saving regs
bx      lr              @ return

@ echoString1.s
@ Prompts user to enter a string, then echoes it.
@ 2017-09-29: Bob Plantz

@ Define my Raspberry Pi
.cpu    cortex-a53
.fpu    neon-fp-armv8
.syntax unified         @ modern syntax

@ Constant for assembler
.equ    nBytes,50  @ amount of memory for string
@ Constant program data
.section .rodata
.align  2
prompt:
.asciz        "Enter some text: "

@ The program
.text
.align  2
.global main
.type   main, %function
main:
sub     sp, sp, 16      @ space for saving regs
@ (keeping 8-byte sp align)
str     r4, [sp, 4]     @ save r4
str     fp, [sp, 8]     @      fp
str     lr, [sp, 12]    @      lr
add     fp, sp, 12      @ set our frame pointer

mov     r0, nBytes      @ get memory from heap
bl      malloc
mov     r4, r0          @ pointer to new memory

ldr     r0, promptAddr  @ prompt user
bl      writeStr

mov     r0, r4          @ get user input

mov     r0, r4          @ echo user input
bl      writeStr

mov     r0, r4          @ free heap memory
bl      free

mov     r0, 0           @ return 0;
ldr     r4, [sp, 4]     @ restore r4
ldr     fp, [sp, 8]     @         fp
ldr     lr, [sp, 12]    @         lr
add     sp, sp, 16      @         sp
bx      lr              @ return

.word    prompt

Exercise4
Solution
@ readLn.s
@ Reads a line (through the '\n') from standard input. Has
@ a size limit. Extra characters and '\n' are ignored. Stores
@ NUL-terminated C string.
@ Calling sequence:
@       r0 <- address of place to store string
@       r1 <- string size limit
@ returns number of characters read, excluding NUL.
@ 2017-09-29: Bob Plantz

@ Define my Raspberry Pi
.cpu    cortex-a53
.fpu    neon-fp-armv8
.syntax unified         @ modern syntax

@ Useful source code constants
.equ    STDIN,0
.equ    NUL,0
.equ    LF,10     @ '\n' under Linux

@ The code
.text
.align  2
sub     sp, sp, 24      @ space for saving regs
@ (keeping 8-byte sp align)
str     r4, [sp, 4]     @ save r4
str     r5, [sp, 8]     @      r5
str     r6, [sp,12]     @      r6
str     fp, [sp, 16]    @      fp
str     lr, [sp, 20]    @      lr
add     fp, sp, 20      @ set our frame pointer

mov     r4, r0          @ r4 = string pointer
mov     r5, 0           @ r5 = count
mov     r6, r1          @ r6 = max chars
sub     r6, 1           @ for NUL

mov     r0, STDIN       @ read from keyboard
mov     r1, r4          @ address of current storage
mov     r2, 1           @ read 1 byte
whileLoop:
ldrb    r3, [r4]        @ get just read char
cmp     r3, LF          @ end of input?
beq     endOfString     @ yes, input done
cmp     r5, r6          @ max chars?
bge     ignore          @ yes, ignore rest
add     r4, r4, 1       @ no, increment pointer var
add     r5, r5, 1       @ count++
ignore:
mov     r0, STDIN       @ read from keyboard
mov     r1, r4          @ address of current storage
mov     r2, 1           @ read 1 byte
b       whileLoop       @ and check for end
endOfString:
mov     r0, NUL         @ string terminator
strb    r0, [r4]        @ write over '\n'

mov     r0, r5          @ return count;
ldr     r4, [sp, 4]     @ restore r4
ldr     r5, [sp, 8]     @      r5
ldr     r6, [sp,12]     @      r6
ldr     fp, [sp, 16]    @      fp
ldr     lr, [sp, 20]    @      lr
add     sp, sp, 24      @      sp
bx      lr              @ return

@ echoString2.s
@ Prompts user to enter a string, then echoes it.
@ 2017-09-29: Bob Plantz

@ Define my Raspberry Pi
.cpu    cortex-a53
.fpu    neon-fp-armv8
.syntax unified         @ modern syntax

@ Constant for assembler
.equ    nBytes,5  @ amount of memory for string
@ Constant program data
.section .rodata
.align  2
prompt:
.asciz        "Enter some text: "

@ The program
.text
.align  2
.global main
.type   main, %function
main:
sub     sp, sp, 16      @ space for saving regs
@ (keeping 8-byte sp align)
str     r4, [sp, 4]     @ save r4
str     fp, [sp, 8]     @      fp
str     lr, [sp, 12]    @      lr
add     fp, sp, 12      @ set our frame pointer

mov     r0, nBytes      @ get memory from heap
bl      malloc
mov     r4, r0          @ pointer to new memory

ldr     r0, promptAddr  @ prompt user
bl      writeStr

mov     r0, r4          @ get user input
mov     r1, nBytes      @ limit input size

mov     r0, r4          @ echo user input
bl      writeStr

mov     r0, r4          @ free heap memory
bl      free

mov     r0, 0           @ return 0;
ldr     r4, [sp, 4]     @ restore r4
ldr     fp, [sp, 8]     @         fp
ldr     lr, [sp, 12]    @         lr
add     sp, sp, 16      @         sp
bx      lr              @ return

.word    prompt

Exercise5
Solution

There are multiple ways to solve this problem. I chose to write a separate function, newLine to give good flexibility in how I display text for users. It is a given that users will want you to change your program's display.

@ newLine.s
@ Writes a newline character to the standard output (screen).
@ Calling sequence:
@       bl    newLine
@ 2017-09-29: Bob Plantz

@ Define my Raspberry Pi
.cpu    cortex-a53
.fpu    neon-fp-armv8
.syntax unified         @ modern syntax

@ Useful source code constants
.equ    STDOUT,1

@ Constant program data
.section .rodata
.align   2
theChar:
.ascii        "\n"

@ The code
.text
.align  2
.global newLine
.type   newLine, %function
newLine:
sub     sp, sp, 8       @ space for fp, lr
str     fp, [sp, 0]     @ save fp
str     lr, [sp, 4]     @   and lr
add     fp, sp, 4       @ set our frame pointer

mov     r0, STDOUT      @ write to screen
mov     r2, 1           @ write 1 byte
bl      write

mov     r0, 0           @ return 0;
ldr     fp, [sp, 0]     @ restore caller fp
ldr     lr, [sp, 4]     @       lr
add     sp, sp, 8       @   and sp
bx      lr              @ return

.word   theChar


Exercises14.2Programming Exercise

Exercise1
Solution
@ lowerCase.s
@ Prompts user to enter alphabetic characters, converts
@ all uppercase to lowercase and shows the result.
@ 2017-09-29: Bob Plantz

@ Define my Raspberry Pi
.cpu    cortex-a53
.fpu    neon-fp-armv8
.syntax unified         @ modern syntax

@ Constant for assembler
.equ    nBytes,50  @ amount of memory for string
@ Constant program data
.section .rodata
.align  2
prompt:
.asciz        "Enter some alphabetic characters: "

@ The program
.text
.align  2
.global main
.type   main, %function
main:
sub     sp, sp, 16      @ space for saving regs
@ (keeping 8-byte sp align)
str     r4, [sp, 4]     @ save r4
str     fp, [sp, 8]     @      fp
str     lr, [sp, 12]    @      lr
add     fp, sp, 12      @ set our frame pointer

mov     r0, nBytes      @ get memory from heap
bl      malloc
mov     r4, r0          @ pointer to new memory

ldr     r0, promptAddr  @ prompt user
bl      writeStr

mov     r0, r4          @ get user input
mov     r1, nBytes      @ limit input size

mov	r0, r4		@ convert to lowercase
bl	toLower

mov     r0, r4          @ echo user input
bl      writeStr

mov     r0, r4          @ free heap memory
bl      free

mov     r0, 0           @ return 0;
ldr     r4, [sp, 4]     @ restore r4
ldr     fp, [sp, 8]     @         fp
ldr     lr, [sp, 12]    @         lr
add     sp, sp, 16      @ restore sp
bx      lr              @ return

.word    prompt

@ toLower.s
@ Converts all alpha characters to lowercase.
@ Calling sequence:
@       r0 <- address of string to be written
@       bl    toLower
@ returns number of characters written
@ 2017-09-29: Bob Plantz

@ Define my Raspberry Pi
.cpu    cortex-a53
.fpu    neon-fp-armv8
.syntax unified         @ modern syntax

@ Useful source code constants
.equ    NUL,0

@ The code
.text
.align  2
.global toLower
.type   toLower, %function
toLower:
sub     sp, sp, 16      @ space for saving regs
str     r4, [sp, 0]     @ save r4
str     r5, [sp, 4]     @      r5
str     fp, [sp, 8]     @      fp
str     lr, [sp, 12]    @      lr
add     fp, sp, 12      @ set our frame pointer

mov     r4, r0          @ r4 = string pointer
mov     r5, #0          @ r5 = count
whileLoop:
ldrb    r3, [r4]        @ get a char
cmp     r3, NUL         @ end of string?
beq     allDone         @ yes, all done

orr     r3, r3, lowerMask  @ convert to lowercase
strb    r3, [r4]        @ update string

add     r4, r4, 1       @ increment pointer var
add     r5, r5, 1       @ count++
allDone:
mov     r0, r5          @ return count;
ldr     r4, [sp, 0]     @ restore r4
ldr     r5, [sp, 4]     @      r5
ldr     fp, [sp, 8]     @         fp
ldr     lr, [sp, 12]    @         lr
add     sp, sp, 16      @ restore sp
bx      lr              @ return


Exercises14.4Programming Exercises

Exercise1
Solution

You will need to copy the assembly language code for hexToInt into a file and then assemble it with:


as --gstabs -o hexToInt2.o hexToInt2.s


Then use gcc to link the object files with the file containing the main function:


gcc -g -o hexConvert1 hexToInt2.o writeStr.o readLn.o hexConvert1.c

Exercise2

It works for both cases because all alphabetic characters are numerically higher than the numeral characters in the ASCII code.

Exercise3
Solution
@ hexConvert2.s
@ Prompts user for hex number and converts
@ it to an int.
@ 2017-09-29: Bob Plantz

@ Define my Raspberry Pi
.cpu    cortex-a53
.fpu    neon-fp-armv8
.syntax unified         @ modern syntax

@ Constant for assembler
.equ    maxChars,9      @ max input chars
.equ    theString,-16   @ for input string
.equ    locals,16       @ space for local vars

@ Constant program data
.section .rodata
.align  2
prompt:
.asciz        "Enter up to 32-bit hex number: "
display:
.asciz        "The integer is: %i\n"

@ The program
.text
.align  2
.global main
.type   main, %function
main:
sub     sp, sp, 8       @ space for fp, lr
str     fp, [sp, 0]     @ save fp
str     lr, [sp, 4]     @   and lr
add     fp, sp, 4       @ set our frame pointer
sub     sp, sp, locals  @ for local vars

ldr     r0, promptAddr  @ prompt user
bl      writeStr

add     r0, fp, theString  @ place for user input
mov     r1, maxChars    @ limit input size

add     r0, fp, theString  @ user input
bl      hexToInt        @ convert it

mov     r1, r0          @ result returned in r0
ldr     r0, displayAddr @ show user the result
bl      printf          @ from C Standard Lib.

mov     r0, 0           @ return 0;
add     sp, sp, locals  @ deallocate local var
ldr     fp, [sp, 0]     @ restore caller fp
ldr     lr, [sp, 4]     @       lr
add     sp, sp, 8       @   and sp
bx      lr              @ return

.word    prompt
.word    display

Exercise4
Solution
@ addHex.s
@ Prompts user for two hex numbers and adds them
@ 2017-09-29: Bob Plantz

@ Define my Raspberry Pi
.cpu    cortex-a53
.fpu    neon-fp-armv8
.syntax unified         @ modern syntax

@ Constant for assembler
.equ    maxChars,9      @ max input chars
.equ    inString1,-24   @ for 1st input string
.equ    inString2,-36   @ for 2nd input string
.equ    outString,-52   @ for output string
.equ    locals,40       @ space for local vars

@ Constant program data
.section .rodata
.align  2
prompt:
.asciz        "Enter up to 32-bit hex number: "
display:
.asciz        "Their sum is: "

@ The program
.text
.align  2
.global main
.type   main, %function
main:
sub     sp, sp, 16      @ space for saving regs
str     r4, [sp, 0]     @ save r4
str     r5, [sp, 4]     @      r5
str     fp, [sp, 8]     @      fp
str     lr, [sp, 12]    @      lr
add     fp, sp, 12      @ set our frame pointer
sub     sp, sp, locals  @ for local vars

ldr     r0, promptAddr  @ prompt user
bl      writeStr

add     r0, fp, inString1  @ 1st input
mov     r1, maxChars    @ limit input size
add     r0, fp, inString1  @ user input
bl      hexToInt        @ convert it
mov     r4, r0          @ 1st int

ldr     r0, promptAddr  @ prompt for 2nd
bl      writeStr

add     r0, fp, inString2  @ 2nd input
mov     r1, maxChars    @ limit input size
add     r0, fp, inString2  @ user input
bl      hexToInt        @ convert it
mov     r5, r0          @ 2nd int

add     r0, fp, outString  @ place for result
bl      intToHex        @ convert to hex string

ldr     r0, displayAddr @ show user result
bl      writeStr

bl      writeStr

bl      newLine         @ looks nicer

mov     r0, 0           @ return 0;
add     sp, sp, locals  @ deallocate local var
ldr     r4, [sp, 0]     @ restore r4
ldr     r5, [sp, 4]     @      r5
ldr     fp, [sp, 8]     @         fp
ldr     lr, [sp, 12]    @         lr
add     sp, sp, 16      @ restore sp
bx      lr              @ return

.word    prompt
.word    display


Exercises14.7Programming Exercises

Exercise1
Solution

The writeStr, readLn, newLine, uDecToInt, and uIntToDec functions have been provided earlier in the book. Here is the main function to solve this problem.

@ incrementDec.s
@ Prompts user for unsigned decimal number and adds 1 to it.
@ 2017-09-29: Bob Plantz

@ Define my Raspberry Pi
.cpu    cortex-a53
.fpu    neon-fp-armv8
.syntax unified         @ modern syntax

@ Constants for assembler
.equ    maxChars,11     @ max input chars
.equ    inputString,-16 @ for input string
.equ    outputString,-28 @ for output string
.equ    locals,32       @ space for local vars

@ Constant program data
.section .rodata
.align  2
prompt:
.asciz        "Enter an unsigned number up to 4294967294: "

@ The program
.text
.align  2
.global main
.type   main, %function
main:
sub     sp, sp, 8       @ space for fp, lr
str     fp, [sp, 0]     @ save fp
str     lr, [sp, 4]     @   and lr
add     fp, sp, 4       @ set our frame pointer
sub     sp, sp, locals  @ for local vars

ldr     r0, promptAddr  @ prompt user
bl      writeStr

add     r0, fp, inputString  @ place for user input
mov     r1, maxChars    @ limit input size

add     r0, fp, inputString  @ user input
bl      uDecToInt       @ convert it

add     r1, r0, 1       @ increment user's number
bl      uIntToDec

bl      writeStr
bl      newLine

mov     r0, 0           @ return 0;
add     sp, sp, locals  @ deallocate local var
ldr     fp, [sp, 0]     @ restore caller fp
ldr     lr, [sp, 4]     @       lr
add     sp, sp, 8       @   and sp
bx      lr              @ return

.word    prompt

Exercise2
Solution
@ uIntToDecMls.s
@ Converts an int to the corresponding unsigned
@ decimal text string.
@ Calling sequence:
@       r0 <- address of place to store string
@       r1 <- int to convert
@       bl uIntToDec
@ 2017-09-29: Bob Plantz
@ 2017-09-30: Use mls for remainder comp - Bob Plantz

@ Define my Raspberry Pi
.cpu    cortex-a53
.fpu    neon-fp-armv8
.syntax unified         @ modern syntax

@ Constant for assembler
.equ    tempString,-40  @ for temp string
.equ    locals,16       @ space for local vars
.equ    zero,0x30       @ ascii 0
.equ    NUL,0

@ The program
.text
.align  2
.global uIntToDec
.type   uIntToDec, %function
uIntToDec:
sub     sp, sp, 24      @ space for saving regs
str     r4, [sp, 0]     @ save r4
str     r5, [sp, 4]     @      r5
str     r6, [sp, 8]     @      r6
str     r7, [sp, 12]    @      r7
str     fp, [sp, 16]    @      fp
str     lr, [sp, 20]    @      lr
add     fp, sp, 20      @ set our frame pointer
sub     sp, sp, locals @ for local vars

mov     r4, r0          @ caller's string pointer
add     r5, fp, tempString @ temp string
mov     r7, 10          @ decimal constant

mov     r0, NUL         @ end of C string
strb    r0, [r5]
add     r5, r5, 1       @ move to char storage

mov     r0, zero        @ assume the int is 0
strb    r0, [r5]
movs    r6, r1          @ int to convert
beq     copyLoop        @ zero is special case
convertLoop:
cmp     r6, 0           @ end of int?
beq     copy            @ yes, copy for caller
udiv    r0, r6, r7      @ no, div to get quotient
mls     r2, r0, r7, r6  @ the mod (remainder)
mov     r6, r0          @ the quotient
orr     r2, r2, zero    @ convert to numeral
strb    r2, [r5]
add     r5, r5, 1       @ next char position
b       convertLoop
copy:
sub     r5, r5, 1       @ last char stored locally
copyLoop:
ldrb    r0, [r5]        @ get local char
strb    r0, [r4]        @ store the char for caller
cmp     r0, NUL         @ end of local string?
beq     allDone         @ yes, we're done
add     r4, r4, 1       @ no, next caller location
sub     r5, r5, 1       @ next local char
b       copyLoop

allDone:
strb    r0, [r4]        @ end C string
add     sp, sp, locals  @ deallocate local var
ldr     r4, [sp, 0]     @ restore r4
ldr     r5, [sp, 4]     @      r5
ldr     r6, [sp, 8]     @      r6
ldr     r7, [sp, 12]    @      r7
ldr     fp, [sp, 16]    @      fp
ldr     lr, [sp, 20]    @      lr
add     sp, sp, 24      @      sp
bx      lr              @ return

Exercise3
Solution
@ incrementSigned.s
@ Prompts user for signed decimal number and adds 1 to it.
@ 2017-09-29: Bob Plantz

@ Define my Raspberry Pi
.cpu    cortex-a53
.fpu    neon-fp-armv8
.syntax unified         @ modern syntax

@ Constant program data
.section .rodata
.align  2
prompt:
.asciz        "Enter a signed integer between -2147483648 and +2147483646: "

@ The program
.text
.align  2
.global main
.type   main, %function
main:
sub     sp, sp, 8       @ space for fp, lr
str     fp, [sp, 0]     @ save fp
str     lr, [sp, 4]     @   and lr
add     fp, sp, 4       @ set our frame pointer

ldr     r0, promptAddr  @ prompt user
bl      writeStr

bl      getDecInt       @ convert it

add     r0, r0, 1       @ increment user's number
bl      putDecInt       @ print result
bl      newLine

mov     r0, 0           @ return 0;
ldr     fp, [sp, 0]     @ restore caller fp
ldr     lr, [sp, 4]     @       lr
add     sp, sp, 8       @   and sp
bx      lr              @ return

.word    prompt

@ getDecInt.s
@ Gets signed decimal integer from keyboard.
@ Calling sequence:
@       bl getDecInt
@ returns equivalent int
@ 2017-09-29: Bob Plantz

@ Define my Raspberry Pi
.cpu    cortex-a53
.fpu    neon-fp-armv8
.syntax unified         @ modern syntax

@ Constants for assembler
.equ    maxChars,12     @ max input chars
.equ    inputString,-20 @ for input string
.equ    locals,8        @ space for local vars

@ Useful source code constants
.equ    POS,0
.equ    NEG,1

@ The program
.text
.align  2
.global getDecInt
.type   getDecInt, %function
getDecInt:
sub     sp, sp, 16      @ space for saving regs
@ (keeping 8-byte sp align)
str     r4, [sp, 4]     @ save r4
str     fp, [sp, 8]     @      fp
str     lr, [sp, 12]    @      lr
add     fp, sp, 12      @ set our frame pointer
sub     sp, sp, locals  @ for the string

add     r0, fp, inputString  @ place to store input
mov     r1, maxChars    @ limit input length

add     r0, fp, inputString  @ input string
mov     r4, POS         @ assume postive int

ldrb    r1, [r0]        @ get char
cmp     r1, '-          @ minus sign?
bne     checkPlus       @ no, check for plus sign
mov     r4, NEG         @ yes, flag as neg
add     r0, r0, 1       @ go to the number
b       convert         @ and convert it
checkPlus:
cmp     r1, '+          @ plus sign?
bne     convert         @ no, we're at the number
add     r0, r0, 1       @ go to the number
convert:
bl      uDecToInt

cmp     r4, POS         @ positive int?
beq     allDone         @ yes, we're done
mvn     r0, r0          @ no, complement it
add     r0, r0, 1       @ and finish negate
allDone:
add     sp, sp, locals  @ deallocate local var
ldr     r4, [sp, 4]     @ restore r4
ldr     fp, [sp, 8]     @         fp
ldr     lr, [sp, 12]    @         lr
add     sp, sp, 16      @         sp
bx      lr              @ return

@ putDecInt.s
@ Converts an int to the corresponding signed
@ decimal text string.
@ Calling sequence:
@       r0 <- int to print
@       bl putDecInt
@ 2017-09-29: Bob Plantz

@ Define my Raspberry Pi
.cpu    cortex-a53
.fpu    neon-fp-armv8
.syntax unified         @ modern syntax

@ Constants for assembler
.equ    decString,-20   @ for  string
.equ    locals,8        @ space for local varsbr

@ Useful source code constants
.equ    POS,0
.equ    NEGBIT,0x80000000

@ The program
.text
.align  2
.global putDecInt
.type   putDecInt, %function
putDecInt:
sub     sp, sp, 16      @ space for saving regs
@ (keeping 8-byte sp align)
str     r4, [sp, 4]     @ save r4
str     fp, [sp, 8]     @      fp
str     lr, [sp, 12]    @      lr
add     fp, sp, 12      @ set our frame pointer
sub     sp, sp, locals  @ space for the string

add     r4, fp, decString  @ place to store string
mov     r1, '+          @ assume positive
strb    r1, [r4]
tst     r0, NEGBIT      @ negative int?
beq     positive        @ no, go on
mov     r1, '-          @ yes, need to negate
strb    r1, [r4]
mvn     r0, r0          @ complement
add     r0, r0, 1       @ two's complement
positive:
mov     r1, r0          @ int to convert
add     r0, r4, 1       @ skip over sign char
bl      uIntToDec

add     r0, fp, decString  @ string to write
bl      writeStr

add     sp, sp, locals  @ deallocate local var
ldr     r4, [sp, 4]     @ restore r4
ldr     fp, [sp, 8]     @         fp
ldr     lr, [sp, 12]    @         lr
add     sp, sp, 16      @         sp
bx      lr              @ return


Exercises15.2Programming Exercise

Exercise1
Solution
@ reverseArray.s
@ Gets 10 integers from user then prints in reverse order.
@ 2017-09-29: Bob Plantz

@ Define my Raspberry Pi
.cpu    cortex-a53
.fpu    neon-fp-armv8
.syntax unified         @ modern syntax

@ Constants for assembler
.equ    nElements,10    @ number of elements in array
.equ    intArray,-52    @ array beginning
.equ    locals,40       @ space for local vars

@ Constant program data
.section .rodata
.align  2
prompt:
.asciz        "Enter an integer:\n"
display:
.asciz        "In reverse order:\n"

@ The program
.text
.align  2
.global main
.type   main, %function
main:
sub     sp, sp, 16      @ space for saving regs
str     r4, [sp, 0]     @ save r4
str     r5, [sp, 4]     @      r5
str     fp, [sp, 8]     @      fp
str     lr, [sp, 12]    @      lr
add     fp, sp, 12      @ set our frame pointer
sub     sp, sp, locals  @ for the array

mov     r5, 0           @ index = 0;
fillLoop:
cmp     r5, nElements   @ all filled?
bge     allFull         @ yes
ldr     r0, promptAddr  @ no, prompt user
bl      writeStr
bl      getDecInt       @ get integer
lsl     r1, r5, 2       @ offset is 4 * index
str     r0, [r4, r1]    @ at index-th element
add     r5, r5, 1       @ index++;
b       fillLoop
allFull:
ldr     r0, displayAddr @ nice message
bl      writeStr

mov     r5, 9           @ index = 9;
printLoop:
lsl     r1, r5, 2       @ no, offset is 4 * index
ldr     r0, [r4, r1]    @ at index-th element
bl      putDecInt       @ print integer
bl      newLine
subs    r5, r5, 1       @ index--;
bge     printLoop
allDone:
mov     r0, 0           @ return 0;
add     sp, sp, locals  @ deallocate local var
ldr     r4, [sp, 0]     @ restore r4
ldr     r5, [sp, 4]     @      r5
ldr     fp, [sp, 8]     @         fp
ldr     lr, [sp, 12]    @         lr
add     sp, sp, 16      @ restore sp
bx      lr              @ return

.word    prompt
.word    display


Exercises15.5Programming Exercise

Exercise1
Solution
@ structPass3.s
@ Allocates two structs and gets values for user for
@ each struct, then displays the values.
@ 2017-09-29: Bob Plantz

@ Define my Raspberry Pi
.cpu    cortex-a53
.fpu    neon-fp-armv8
.syntax unified         @ modern syntax

@ Constants for assembler
.include "theTagStruct.s"  @ theTag struct defs.
.equ    y,-36           @ y struct
.equ    x,-24           @ x struct
.equ    locals,24       @ space for the structs

@ Constant program data
.section .rodata
.align  2
displayX:
.asciz        "x fields:\n"
displayY:
.asciz        "y fields:\n"

@ The program
.text
.align  2
.global main
.type   main, %function
main:
sub     sp, sp, 16      @ space for saving regs
@ (keeping 8-byte sp align)
str     r4, [sp, 4]     @ save r4
str     fp, [sp, 8]     @      fp
str     lr, [sp, 12]    @      lr
add     fp, sp, 12      @ set our frame pointer
sub     sp, sp, locals  @ for the structs

@ fill the x struct
bl      getStruct

@ fill the y struct
bl      getStruct

@ display x struct
bl      writeStr
bl      putStruct
bl      newLine

@ display y struct
bl      writeStr
bl      putStruct
bl      newLine

mov     r0, 0           @ return 0;
add     sp, sp, locals  @ deallocate local var
ldr     r4, [sp, 4]     @ restore r4
ldr     fp, [sp, 8]     @         fp
ldr     lr, [sp, 12]    @         lr
add     sp, sp, 16      @         sp
bx      lr              @ return

.align  2
.word   displayX
.word   displayY

@ getStruct.s
@ Gets values for a theTag struct from keyboard
@ Calling sequence:
@        r0 <- address of the struct
@        bl  getStruct
@ Returns 0
@ 2017-09-29: Bob Plantz

@ Define my Raspberry Pi
.cpu    cortex-a53
.fpu    neon-fp-armv8
.syntax unified         @ modern syntax

@ Constants for assembler
.include "theTagStruct.s"  @ theTag struct defs.

@ Constant program data
.section .rodata
.align  2
charPrompt:
.asciz        "Enter a character: "
intPrompt:
.asciz        "Enter an integer: "

@ The program
.text
.align  2
.global getStruct
.type   getStruct, %function
getStruct:
sub     sp, sp, 16      @ space for saving regs
@ (keeping 8-byte sp align)
str     r4, [sp, 4]     @ save r4
str     fp, [sp, 8]     @      fp
str     lr, [sp, 12]    @      lr
add     fp, sp, 12      @ set our frame pointer

mov     r4, r0          @ pointer to the struct

bl      writeStr        @ ask for a char
bl      getChar         @ get it
strb    r0, [r4, aChar] @ aStruct->aChar = firstChar;

bl      writeStr        @ ask for a char
bl      getDecInt       @ get it
str     r0, [r4, anInt] @ aStruct->anInt = aNumber;

bl      writeStr        @ ask for a char
bl      getChar         @ get it
strb    r0, [r4, anotherChar] @ aStruct->anotherChar = secondChar;

mov     r0, 0           @ return 0;
ldr     r4, [sp, 4]     @ restore r4
ldr     fp, [sp, 8]     @         fp
ldr     lr, [sp, 12]    @         lr
add     sp, sp, 16      @         sp
bx      lr              @ return

.align  2
.word   charPrompt
.word   intPrompt

@ putStruct.s
@ Displays values for a theTag struct on screen
@ Calling sequence:
@        r0 <- address of the struct
@        bl  putStruct
@ Returns 0
@ 2017-09-29: Bob Plantz

@ Define my Raspberry Pi
.cpu    cortex-a53
.fpu    neon-fp-armv8
.syntax unified         @ modern syntax

@ Constants for assembler
.include "theTagStruct.s"  @ theTag struct defs.

@ Constant program data
.section .rodata
.align  2
dispAChar:
.asciz        "         aChar = "
dispAnInt:
.asciz        "         anInt = "
dispOtherChar:
.asciz        "   anotherChar = "

@ The program
.text
.align  2
.global putStruct
.type   putStruct, %function
putStruct:
sub     sp, sp, 16      @ space for saving regs
@ (keeping 8-byte sp align)
str     r4, [sp, 4]     @ save r4
str     fp, [sp, 8]     @      fp
str     lr, [sp, 12]    @      lr
add     fp, sp, 12      @ set our frame pointer

mov     r4, r0             @ pointer to the struct

ldr     r0, dispACharAddr  @ display aChar
bl      writeStr
ldrb    r0, [r4, aChar]
bl      putChar
bl      newLine
ldr     r0, dispAnIntAddr  @ display anInt
bl      writeStr
ldr     r0, [r4, anInt]
bl      putDecInt
bl      newLine
ldr     r0, dispOtherCharAddr @ display anotherChar
bl      writeStr
ldrb    r0, [r4, anotherChar]
bl      putChar
bl      newLine

mov     r0, 0              @ return 0;
ldr     r4, [sp, 4]     @ restore r4
ldr     fp, [sp, 8]     @         fp
ldr     lr, [sp, 12]    @         lr
add     sp, sp, 16      @         sp
bx      lr              @ return

.align  2
.word   dispAChar
.word   dispAnInt
.word   dispOtherChar

@ getChar.s
@ Gets one char from keyboard.
@ Calling sequence:
@       bl getChar
@ returns char in low byte of r0
@ 2017-09-29: Bob Plantz

@ Define my Raspberry Pi
.cpu    cortex-a53
.fpu    neon-fp-armv8
.syntax unified         @ modern syntax

@ Constants for assembler
.equ    maxChars,2      @ max input chars
.equ    inputChar,-12   @ for input chars
.equ    locals,8        @ space for local vars

@ The program
.text
.align  2
.global getChar
.type   getChar, %function
getChar:
sub     sp, sp, 8       @ space for fp, lr
str     fp, [sp, 0]     @ save fp
str     lr, [sp, 4]     @   and lr
add     fp, sp, 4       @ set our frame pointer
sub     sp, sp, locals  @ for the string

add     r0, fp, inputChar  @ place to store input
mov     r1, maxChars    @ limit input length

ldrb    r0, [fp, inputChar] @ return inputChar

add     sp, sp, locals  @ deallocate local var
ldr     fp, [sp, 0]     @ restore caller fp
ldr     lr, [sp, 4]     @       lr
add     sp, sp, 8       @   and sp
bx      lr              @ return


Exercises15.7Programming Exercise

Exercise1
Solution
@ incFraction.s
@ Gets values from user for a fraction, adds 1
@ to the fraction, and then displays the result.
@ 2017-09-29: Bob Plantz

@ Define my Raspberry Pi
.cpu    cortex-a53
.fpu    neon-fp-armv8
.syntax unified         @ modern syntax

@ Constants for assembler
.equ    x,-12           @ x fraction object
.equ    locals,8        @ space for fraction

@ The program
.text
.align  2
.global main
.type   main, %function
main:
sub     sp, sp, 8       @ space for fp, lr
str     fp, [sp, 0]     @ save fp
str     lr, [sp, 4]     @   and lr
add     fp, sp, 4       @ set our frame pointer
sub     sp, sp, locals  @ for the structs

@ construct the fraction
bl      fractionConstr

@ get user input
add     r0, fp, x       @ get user values
bl      fractionGet

mov     r1, 1

@ display result
add     r0, fp, x       @ get user values
bl      fractionDisplay

mov     r0, 0           @ return 0;
add     sp, sp, locals  @ deallocate local var
ldr     fp, [sp, 0]     @ restore caller fp
ldr     lr, [sp, 4]     @       lr
add     sp, sp, 8       @   and sp
bx      lr              @ return

@ fractionObject.s
@ field name definitions; requires 8 bytes
@ 2017-09-29: Bob Plantz

@ fraction object definition
.equ    num,0    @ numerator
.equ    den,4    @ denominator

@ fractionConstr.s
@ Construct a fraction object
@ Calling sequence:
@        r0 <- address of fraction variable
@        bl  fractionConstr
@ Returns 0
@ 2017-09-29: Bob Plantz

@ Define my Raspberry Pi
.cpu    cortex-a53
.fpu    neon-fp-armv8
.syntax unified         @ modern syntax

@ Constants for assembler
.include "fractionObject.s"  @ fraction object defs.

@ The code
.text
.align  2
.global fractionConstr
.type   fractionConstr, %function
fractionConstr:
sub     sp, sp, 8       @ space for fp, lr
str     fp, [sp, 0]     @ save fp
str     lr, [sp, 4]     @   and lr
add     fp, sp, 4       @ set our frame pointer

mov     r1, 1           @ reasonable numerator
str     r1, [r0, num]

mov     r1, 2           @ reasonable denominator
str     r1, [r0, den]

mov     r0, 0           @ return 0;
ldr     fp, [sp, 0]     @ restore caller fp
ldr     lr, [sp, 4]     @       lr
add     sp, sp, 8       @   and sp
bx      lr              @ return

@ fractionGet.s
@ Gets values for a fraction from keyboard
@ Calling sequence:
@        r0 <- address of the struct
@        bl  getStruct
@ Returns 0
@ 2017-09-29: Bob Plantz

@ Define my Raspberry Pi
.cpu    cortex-a53
.fpu    neon-fp-armv8
.syntax unified         @ modern syntax

@ Constants for assembler
.include "fractionObject.s"  @ fraction object defs.

@ Constant program data
.section .rodata
.align  2
numPrompt:
.asciz        "  Enter numerator: "
denPrompt:
.asciz        "Enter denominator: "

@ The code
.text
.align  2
.global fractionGet
.type   fractionGet, %function
fractionGet:
sub     sp, sp, 16      @ space for saving regs
@ (keeping 8-byte sp align)
str     r4, [sp, 4]     @ save r4
str     fp, [sp, 8]     @      fp
str     lr, [sp, 12]    @      lr
add     fp, sp, 12      @ set our frame pointer

mov     r4, r0          @ pointer to the object

bl      writeStr        @ ask for numerator
bl      getDecInt       @ get it
str     r0, [r4, num]   @ store at this->num

bl      writeStr        @ ask for denominator
bl      getDecInt       @ get it
str     r0, [r4, den]   @ store at this->den

mov     r0, 0           @ return 0;
ldr     r4, [sp, 4]     @ restore r4
ldr     fp, [sp, 8]     @         fp
ldr     lr, [sp, 12]    @         lr
add     sp, sp, 16      @         sp
bx      lr              @ return

.align  2
.word   numPrompt
.word   denPrompt

@ fractionAddInt.s
@ Adds an integer to a fraction
@ Assumes (int X den) + num fits into 32 bits.
@ Calling sequence:
@        r0 <- address of the object
@        r1 <- integer to add
@ Returns 0
@ 2017-09-29: Bob Plantz

@ Define my Raspberry Pi
.cpu    cortex-a53
.fpu    neon-fp-armv8
.syntax unified         @ modern syntax

@ Constants for assembler
.include "fractionObject.s"  @ fraction object defs.

@ The code
.text
.align  2
sub     sp, sp, 16      @ space for saving regs
@ (keeping 8-byte sp align)
str     r4, [sp, 4]     @ save r4
str     fp, [sp, 8]     @      fp
str     lr, [sp, 12]    @      lr
add     fp, sp, 12      @ set our frame pointer

mov     r4, r0          @ this pointer

ldr     r0, [r4, den]   @ get denominator
mul     r2, r1, r0      @ integer X denominator
ldr     r0, [r4, num]   @ get numerator
add     r2, r2, r0      @ numerator + (int X den)
str     r2, [r4, num]   @ save new numerator

mov     r0, 0           @ return 0;
ldr     r4, [sp, 4]     @ restore r4
ldr     fp, [sp, 8]     @         fp
ldr     lr, [sp, 12]    @         lr
add     sp, sp, 16      @         sp
bx      lr              @ return

@ fractionDisplay.s
@ Displays a fraction struct on screen
@ Calling sequence:
@        r0 <- address of the struct
@        bl  fractionDisplay
@ Returns 0
@ 2017-09-29: Bob Plantz

@ Define my Raspberry Pi
.cpu    cortex-a53
.fpu    neon-fp-armv8
.syntax unified         @ modern syntax

@ Constants for assembler
.include "fractionObject.s"  @ fraction object defs.

@ The code
.text
.align  2
.global fractionDisplay
.type   fractionDisplay, %function
fractionDisplay:
sub     sp, sp, 16      @ space for saving regs
@ (keeping 8-byte sp align)
str     r4, [sp, 4]     @ save r4
str     fp, [sp, 8]     @      fp
str     lr, [sp, 12]    @      lr
add     fp, sp, 12      @ set our frame pointer

mov     r4, r0          @ this pointer

ldr     r0, [r4, num]   @ display numerator
bl      putDecInt
mov     r0, '/          @ slash for fraction
bl      putChar
ldr     r0, [r4, den]   @ display denominator
bl      putDecInt
bl      newLine

mov     r0, 0           @ return 0;
ldr     r4, [sp, 4]     @ restore r4
ldr     fp, [sp, 8]     @         fp
ldr     lr, [sp, 12]    @         lr
add     sp, sp, 16      @         sp
bx      lr              @ return

@ putChar.s
@ Writes a character to the standard output (screen).
@ Calling sequence:
@       r0 <- the character
@       bl    putChar
@ 2017-09-29: Bob Plantz

@ Define my Raspberry Pi
.cpu    cortex-a53
.fpu    neon-fp-armv8
.syntax unified         @ modern syntax

@ Constants for assembler
.equ    STDOUT,1
.equ    theChar,-5     @ for  string
.equ    locals,8       @ space for local var

@ The code
.text
.align  2
.global putChar
.type   putChar, %function
putChar:
sub     sp, sp, 8       @ space for fp, lr
str     fp, [sp, 0]     @ save fp
str     lr, [sp, 4]     @   and lr
add     fp, sp, 4       @ set our frame pointer
sub     sp, sp, locals

strb    r0, [fp, theChar]  @ write needs address
mov     r0, STDOUT      @ write to screen
mov     r2, 1           @ write 1 byte
bl      write

mov     r0, 0           @ return 0;
add     sp, sp, locals  @ deallocate local var
ldr     fp, [sp, 0]     @ restore caller fp
ldr     lr, [sp, 4]     @       lr
add     sp, sp, 8       @   and sp
bx      lr              @ return


Exercises16.2Programming Exercise

Exercise1
Solution

Refer to Equation (16.1.1).

• $i = -1$
• While ($F \ne 0$) AND (want-more-bits)

• $F = 2 \times F$

• $d_{i} = int(F)$

• $F = F - d_{i}$

• $i = i - 1$

Exercises16.6Exercises

Exercise1
Solution

1. Compute $s\text{,}$ $e+127\text{,}$ and $f\text{.}$

\begin{align*} s &= \binary{0}\\ e + 127 &= \binary{00000000}_{2}\\ e &= -127_{10}\\ f &= \binary{00000000000000000000000} \end{align*}
2. Finally, plug these values into Equation (16.5.1). (Remember to add the hidden bit.)

\begin{align*} (-1)^0 \times 1.00\dots 00 \times 2^{-127} &= \mbox{a very small number}\\ &\ne 0.0 \end{align*}

so we do need the special case.

Exercise2

1. $\hex{3f80 0000}$

2. $\hex{bdcc cccd}$

3. $\hex{44fc 0000}$

4. $\hex{3b80 0000}$

5. $\hex{c543 5500}$

6. $\hex{3ea8 f5c3}$

7. $\hex{3f2b 851f}$

8. $\hex{4048 f5c3}$

Exercise3

1. $+2.0$

2. $-1.0$

3. $+0.0625$

4. $-16.03125$

5. $100.03125$

6. $1.2$

7. $123.449997$

8. $-54.320999$

Exercises18.6Programming Exercise

Exercise1
Solution
@ locatePeripherals.s
@ Determines the beginning address of peripherals.
@ 2017-09-29: Bob Plantz

@ Define my Raspberry Pi
.cpu    cortex-a53
.fpu    neon-fp-armv8
.syntax unified         @ modern syntax

@ Constant program data
.section  .rodata
.align  2
formatMsg:
.asciz	 "Peripheral addresses begin at %p\n"

@ Program code
.text
.align  2
.global main
.type   main, %function
main:
sub     sp, sp, 8       @ space for fp, lr
str     fp, [sp, 0]     @ save fp
str     lr, [sp, 4]     @   and lr
add     fp, sp, 4       @ set our frame pointer

mov     r1, r0          @ argument for printf
ldr     r0, formatMsgAddr  @ printf("%i + %i = %i\n",
bl      printf

mov     r0, 0           @ return 0;
ldr     fp, [sp, 0]     @ restore caller fp
ldr     lr, [sp, 4]     @       lr
add     sp, sp, 8       @   and sp
bx      lr              @ return
bx      lr              @ return

.align  2
.word   formatMsg


Exercises19.3Programming Exercise

Exercise1
Solution

See Listing 19.2.6 for gpioPinFSelect and Listing 19.2.8 for gpioPinSet.

@ blinkLED.s
@ Blinks LED connected between pins 1 and 11 on Raspberry Pi
@ GPIO connector once a second for five seconds.
@ 2017-09-30: Bob Plantz

@ Define my Raspberry Pi
.cpu    cortex-a53
.fpu    neon-fp-armv8
.syntax unified         @ modern syntax

@ Constants for assembler
.equ    PERIPH,0x3f000000   @ RPi 2 & 3 peripherals
@        .equ    PERIPH,0x20000000   @ RPi zero & 1 peripherals
.equ    GPIO_OFFSET,0x200000  @ start of GPIO device
@ The following are defined in /usr/include/asm-generic/fcntl.h:
@ Note that the values are specified in octal.
.equ    O_RDWR,00000002   @ open for read/write
.equ    O_DSYNC,00010000
.equ    __O_SYNC,04000000
.equ    O_SYNC,__O_SYNC|O_DSYNC
@ The following are defined in /usr/include/asm-generic/mman-common.h:
.equ    PROT_WRITE,0x2  @ page can be written
.equ    MAP_SHARED,0x01 @ share changes
@ The following are defined by me:
.equ    O_FLAGS,O_RDWR|O_SYNC @ open file flags
.equ    NO_PREF,0
.equ    PAGE_SIZE,4096  @ Raspbian memory page
.equ    INPUT,0         @ use pin for input
.equ    OUTPUT,1        @ use pin for ouput
.equ    ONE_SEC,1       @ sleep one second
.equ    PIN17,17        @ pin set bit
.equ    FILE_DESCRP_ARG,0   @ file descriptor
.equ    STACK_ARGS,8    @ includes sp 8-byte align

@ Constant program data
.section .rodata
.align  2
device:
.asciz  "/dev/gpiomem"
devErr:
.asciz  "Cannot open /dev/gpiomem\n"
memErr:
.asciz  "Cannot map /dev/gpiomem\n"

@ The program
.text
.align  2
.global main
.type   main, %function
main:
sub     sp, sp, 24      @ space for saving regs
@ (keeping 8-byte sp align)
str     r4, [sp, 4]     @ save r4
str     r5, [sp, 8]     @      r5
str     r6, [sp,12]     @      r6
str     fp, [sp, 16]    @      fp
str     lr, [sp, 20]    @      lr
add     fp, sp, 20      @ set our frame pointer
sub     sp, sp, STACK_ARGS

@ Open /dev/gpiomem for read/write and syncing
ldr     r1, openMode    @ flags for accessing device
bl      open
cmp     r0, -1          @ check for error
bne     gpiomemOK       @ no error, continue
ldr     r0, devErrAddr  @ error, tell user
bl      printf
b       allDone         @ and end program

gpiomemOK:
mov     r4, r0          @ use r4 for file descriptor

@ Map the GPIO registers to a main memory location so we can access them
str     r4, [sp, FILE_DESCRP_ARG] @ /dev/gpiomem file descriptor
ldr     r0, gpio        @ address of GPIO
str     r0, [sp, DEVICE_ARG]      @ location of GPIO
mov     r0, NO_PREF     @ let kernel pick memory
mov     r1, PAGE_SIZE   @ get 1 page of memory
mov     r2, PROT_RDWR   @ read/write this memory
mov     r3, MAP_SHARED  @ share with other processes
bl      mmap
cmp     r0, -1          @ check for error
bne     mmapOK          @ no error, continue
ldr     r0, memErrAddr @ error, tell user
bl      printf
b       closeDev        @ and close /dev/gpiomem

@ All OK, blink the LED
mmapOK:
mov     r5, r0          @ use r5 for programming memory address
mov     r0, r5          @ programming memory
mov     r1, PIN17       @ pin to blink
mov     r2, OUTPUT      @ it's an output
bl      gpioPinFSelect  @ select function

mov     r6, 5           @ blink five times
loop:
mov     r0, r5          @ GPIO programming memory
mov     r1, PIN17
bl      gpioPinClr
mov     r0, ONE_SEC     @ wait a second
bl      sleep
mov     r0, r5
mov     r1, PIN17
bl      gpioPinSet
mov     r0, ONE_SEC     @ wait a second
bl      sleep
subs    r6, r6, 1       @ decrement counter
bgt     loop            @ loop until 0

mov     r0, r5          @ memory to unmap
mov     r1, PAGE_SIZE   @ amount we mapped
bl      munmap          @ unmap it

closeDev:
mov     r0, r4          @ /dev/gpiomem file descriptor
bl      close           @ close the file

allDone:
mov     r0, 0           @ return 0;
add     sp, sp, STACK_ARGS  @ fix sp
ldr     r4, [sp, 4]     @ restore r4
ldr     r5, [sp, 8]     @      r5
ldr     r6, [sp,12]     @      r6
ldr     fp, [sp, 16]    @      fp
ldr     lr, [sp, 20]    @      lr
add     sp, sp, 24      @      sp
bx      lr              @ return

.align  2
.word   device
openMode:
.word   O_FLAGS
gpio:
.word   PERIPH+GPIO_OFFSET
.word   devErr
.word   memErr

@ gpioPinClr.s
@ Clears a GPIO pin. Assumes that GPIO registers
@ have been mapped to programming memory.
@ Calling sequence:
@       r0 <- address of GPIO in mapped memory
@       r1 <- pin number
@       bl gpioPinClr
@ 2017-09-30: Bob Plantz

@ Define my Raspberry Pi
.cpu    cortex-a53
.fpu    neon-fp-armv8
.syntax unified         @ modern syntax

@ Constants for assembler
.equ    PIN,1           @ 1 bit for pin
.equ    PINS_IN_REG,32
.equ    GPCLR0,0x28     @ clear register offset

@ The program
.text
.align  2
.global gpioPinClr
.type   gpioPinClr, %function
gpioPinClr:
sub     sp, sp, 16      @ space for saving regs
str     r4, [sp, 0]     @ save r4
str     r5, [sp, 4]     @      r5
str     fp, [sp, 8]     @      fp
str     lr, [sp, 12]    @      lr
add     fp, sp, 12      @ set our frame pointer

add     r4, r0, GPCLR0  @ pointer to GPSET regs.
mov     r5, r1          @ save pin number

@ Compute address of GPSET register and pin field
mov     r3, PINS_IN_REG @ divisor
udiv    r0, r5, r3      @ GPSET number
mul     r1, r0, r3      @ compute remainder
sub     r1, r5, r1      @     for relative pin position
lsl     r0, r0, 2       @ 4 bytes in a register

@ Set up the GPIO pin funtion register in programming memory
ldr     r2, [r0]        @ get entire register
mov     r3, PIN         @ one pin
lsl     r3, r3, r1      @ shift to pin position
orr     r2, r2, r3      @ clear bit
str     r2, [r0]        @ update register

mov     r0, 0           @ return 0;
ldr     r4, [sp, 0]     @ restore r4
ldr     r5, [sp, 4]     @      r5
ldr     fp, [sp, 8]     @         fp
ldr     lr, [sp, 12]    @         lr
add     sp, sp, 16      @ restore sp
bx      lr              @ return