Appendix EExercise Solutions

The solutions to most of the exercises in the book are in this Appendix. You should attempt to work the exercise before looking at the solution. But don’t allow yourself to get bogged down. If the solution does not come to you within a reasonable amount of time, peek at the solution for a hint.

A word of warning: I have proofread these solutions many times. Each time has turned up several errors. I am amazed at how diﬃcult it is to make everything perfect. If you ﬁnd an error, please email me and I will try to correct the next printing.

When reading my programming solutions, be aware that my goal is to present simple, easy-to-read code that illustrates the point. I have not tried to optimize, neither for size nor performance.

I am also aware that each of us has our own programming style. Yours probably diﬀers from mine. If you are working with an instructor, I encourage you to discuss programming style with him or her. I probably will not change my style, but I support other people’s desire to use their own style.

E.2 Data Storage Formats

2 -1

a) 4567 b) 89ab c) fedc d) 0250

2 -2

a) 1000 0011 1010 1111 b) 1001 0000 0000 0001 c) 1010 1010 1010 1010 d) 0101 0101 0101 0101

2 -3

a) 32 b) 48 c) 4 d) 16 e) 8 f) 32

2 -4

a) 2 b) 8 c) 16 d) 3 e) 5 f) 2

2 -5

r = 10, n = 8, d7 = 2, d6 = 9, d5 = 4, d4 = 5, d3 = 8, d2 = 2, d1 = 5, d0 = 4.

r = 16, n = 8, d7 = 2, d6 = 9, d5 = 4, d4 = 5, d3 = 8, d2 = 2, d1 = 5, d0 = 4.

2 -6

a) 170 b) 85 c) 240 d) 15 e) 128 f) 99 g) 123 h) 255
2 -7

a) 43981 b) 4660 c) 65244 d) 2000 e) 32768 f) 1024 g) 65535 h) 12345
2 -8

1. compute the value of each power of 16 in decimal.
2. multiply each power of 16 by its corresponding di.
3. sum the terms.
a) 160 b) 80 c) 255 d) 137 e) 100 f) 12 g) 17 h) 200
2 -9

1. compute the value of each power of 16 in decimal.
2. multiply each power of 16 by its corresponding di.
3. sum the terms.
a) 40960 b) 65535 c) 1024 d) 4369 e) 34952 f) 400 g) 43981 h) 21845
2 -10

a) 64 b) 7b c) 0a d) 58 e) ff f) 10 g) 20 h) 80
2 -11

a) 0400 b) 03e8 c) 8000 d) 7fff e) 0100 f) ffff g) 07d5 h) abcd
2 -12

Since there are 12 values, we need 4 bits. Any 4-bit code would work. For example,

 code grade 0000 A 0001 A- 0010 B+ 0011 B 0100 B- 0101 C+ 0110 C 0111 C- 1000 D+ 1001 D 1010 D- 1011 F
2 -13

The addressing in Figure 2.1 uses only four bits. This limits us to a 16-byte addressing space. In order to increase our space to 17 bytes, we need another bit for the address. The 17th byte would be number 10000.

2 -14

00000000: 106            00000008: 240
00000001: 240            00000009: 2
00000002: 94             0000000a: 51
00000003: 0              0000000b: 60
00000004: 255            0000000c: 195
00000005: 81             0000000d: 60
00000006: 207            0000000e: 85
00000007: 24             0000000f: 170

2 -15

00000000: 0000 0000      00000008: 0000 1000
00000001: 0000 0001      00000009: 0000 1001
00000002: 0000 0010      0000000a: 0000 1010
00000003: 0000 0011      0000000b: 0000 1011
00000004: 0000 0100      0000000c: 0000 1100
00000005: 0000 0101      0000000d: 0000 1101
00000006: 0000 0110      0000000e: 0000 1110
00000007: 0000 0111      0000000f: 0000 1111

2 -16

00000000: 00             00000008: 08
00000001: 01             00000009: 09
00000002: 02             0000000a: 0a
00000003: 03             0000000b: 0b
00000004: 04             0000000c: 0c
00000005: 05             0000000d: 0d
00000006: 06             0000000e: 0e
00000007: 08             0000000f: 0f

2 -17

The range of 32-bit unsigned ints is 0 – 4,294,967,295, so four bytes will be required. If the storage area begins at byte number 0x2fffeb96, the number will also occupy bytes number 0x2fffeb97, 0x2fffeb98, 0x2fffeb99.

2 -18

00001000: 00             0000100f: 0f
00001001: 01             00001010: 10
00001002: 02             00001011: 11
00001003: 03             00001012: 12
00001004: 04             00001013: 13
00001005: 05             00001014: 14
00001006: 06             00001015: 15
00001007: 07             00001016: 16
00001008: 08             00001017: 17
00001009: 09             00001018: 18
0000100a: 0a             00001019: 19
0000100b: 0b             0000101a: 1a
0000100c: 0c             0000101b: 1b
0000100d: 0d             0000101c: 1c
0000100e: 0e             0000101d: 1d

2 -19

0          A
1          B
2          C
3          D
4          F

2 -26

1/*
3 * Asks user to enter a number in decimal or hexadecimal
4 * then echoes it in both bases, also showing where values
5 * are stored.
6 *
7 * Bob Plantz - 19 June 2009
8 */
9
10#include <stdio.h>
11
12int main(void)
13{
14    int x;
15    unsigned int y;
16
17    while(1)
18    {
19        printf("Enter a decimal integer: ");
20        scanf("%i", &x);
21        if (x == 0) break;
22
23        printf("Enter a bit pattern in hexadecimal: ");
24        scanf("%x", &y);
25        if (y == 0) break;
26
27        printf("%i is stored as %#010x at %p, and\n", x, x, &x);
28        printf("%#010x represents the decimal integer %d stored at %p\n\n",
29             y, y, &y);
30    }
31    printf("End of program.\n");
32
33    return 0;
34}
2 -28

1/*
2 * stringInHex.c
3 * displays "Hello world" in hex.
4 *
5 * Bob Plantz - 19 June 2009
6 */
7
8#include <stdio.h>
9
10int main(void)
11{
12    char *stringPtr = "Hello world.\n";
13
14    while (*stringPtr != \0)
15    {
16        printf("%p:  ", stringPtr);
17        printf("0x%02x\n", *stringPtr);
18        stringPtr++;
19    }
20    printf("%p:  ", stringPtr);
21    printf("0x%02x\n", *stringPtr);
22
23    return 0;
24}
2 -29

Keyboard input is line buﬀered by the operating system and is not available to the application program until the user presses the enter key. This action places two characters in the keyboard buﬀer – the character key pressed and the end of line character. (The “end of line” character diﬀers in diﬀerent operating systems.)

The call to the read function gets one character from the keyboard buﬀer – the one corresponding to the key the user pressed. Since there is a breakpoint at the instruction following the call to read, control returns to the debugger, gdb. But the end of line character is still in the keyboard buﬀer, and the operating system dutifully provides it to gdb.

The net result is the same as if you had pushed the enter key immediately in response to gdb’s prompt. This causes gdb to execute the previous command, which was the continue command. So the program immediately loops back to its prompt.

Experiment with this. Try to enter more than one character before pressing the enter key. It is all very consistent. You just have to think through exactly which keys you are pressing when using the debugger to determine what your call to read are doing.

2 -30

1/*
2 * echoString1.c
3 * Echoes a string entered by user.
4 *
5 * Bob Plantz - 19 June 2009
6 */
7
8#include <unistd.h>
9#include <string.h>
10
11int main(void)
12{
13    char aString[200];
14    char *stringPtr = aString;
15
16    write(STDOUT_FILENO, "Enter a text string: ",
17         strlen("Enter a text string: "));  // prompt user
18
19    read(STDIN_FILENO, stringPtr, 1);       // get first character
20    while (*stringPtr != \n)              // look for end of line
21    {
22        stringPtr++;                        // move to next location
23        read(STDIN_FILENO, stringPtr, 1);   // get next characte
24    }
25
26    // now echo for user
27    write(STDOUT_FILENO, "You entered:\n",
28         strlen("You entered:\n"));
29    stringPtr = aString;
30    do
31    {
32        write(STDOUT_FILENO, stringPtr, 1);
33        stringPtr++;
34    } while (*stringPtr != \n);
35    write(STDOUT_FILENO, stringPtr, 1);
36
37    return 0;
38}
2 -31

1/*
2 * echoString2.c
3 * Echoes a string entered by user. Converts input
4 * to C-style string.
5 * Bob Plantz - 19 June 2009
6 */
7
8#include <stdio.h>
9#include <unistd.h>
10#include <string.h>
11
12int main(void)
13{
14    char aString[200];
15    char *stringPtr = aString;
16
17    write(STDOUT_FILENO, "Enter a text string: ",
18         strlen("Enter a text string: ")); // prompt user
19
20    read(STDIN_FILENO, stringPtr, 1);      // get first character
21    while (*stringPtr != \n)             // look for end of line
22    {
23        stringPtr++;                       // move to next location
24        read(STDIN_FILENO, stringPtr, 1);  // get next character
25    }
26    *stringPtr = \0;                     // make into C string
27
28    // now echo for user
29    printf("You entered:\n%s\n", aString);
30
31    return 0;
32}
2 -32

1/*
2 * echoString3.c
3 * Echoes a string entered by user.
4 *
5 * Bob Plantz - 19 June 2009
6 */
7
9#include "writeStr.h"
10
11int main(void)
12{
13    char aString[STRLEN];  // limited to 5 for testing readStr
14                      // change to 200 for use
15    writeStr("Enter a text string: ");
17    writeStr("You entered:\n");
18    writeStr(aString);
19    writeStr("\n");
20
21    return 0;
22}

1/*
2 * writeStr.h
3 * Writes a line to standard out.
4 *
5 * input:
6 *    pointer to C-style text string
7 * output:
8 *    to screen
9 *    returns number of chars written
10 *
11 * Bob Plantz - 19 June 2009
12 */
13
14#ifndef WRITESTR_H
15#define WRITESTR_H
16int writeStr(char *);
17#endif

1/*
2 * writeStr.c
3 * Writes a line to standard out.
4 *
5 * input:
6 *    pointer to C-style text string
7 * output:
8 *    to screen
9 *    returns number of chars written
10 *
11 * Bob Plantz - 19 June 2009
12 */
13
14#include <unistd.h>
15#include "writeStr.h"
16
18{
19    int count = 0;
20
22    {
24        count++;
26    }
27
28    return count;
29}

1/*
3 * Reads a line from standard in.
4 * Drops newline character. Eliminates
5 * excess characters from input buffer.
6 *
7 * input:
8 *    from keyboard
9 * output:
10 *    null-terminated text string
11 *    returns number of chars in text string
12 *
13 * Bob Plantz - 19 June 2009
14 */
15
19#endif

1/*
3 * Reads a line from standard in.
4 * Drops newline character. Eliminates
5 * excess characters from input buffer.
6 *
7 * input:
8 *    from keyboard
9 * output:
10 *    null-terminated text string
11 *    returns number of chars in text string
12 *
13 * Bob Plantz - 19 June 2009
14 */
15
16#include <unistd.h>
18
20{
21    int count = 0;
22    maxLength--;          // allow space for NUL
25    {
26        if (count < maxLength)
27        {
28            count++;
30        }
32    }
33    *stringAddr = \0;   // terminate C string
34
35   return count;
36}

E.3 Computer Arithmetic

3 -1

four

3 -2

Store a digit in every four bits. Thus, the lowest-order digit would be stored in bits 7 – 0, the next lowest-order in 15 – 8, etc., with the highest-order digit in bits 31 – 24.

No, binary addition does not work. For example, let’s consider 48 + 27:

3 -3

3 -4

No, it doesn’t work. The problem is that the range of 4-bit signed numbers in two’s complement format is 8 x +7, and (+4) + (+5) exceeds this range.

3 -5

No, it doesn’t work. The problem is that the range of 4-bit signed numbers in two’s complement format is 8 x +7, and (4) + (5) exceeds this range.

3 -6

Adding any number to its negative will set the CF to one and the OF to zero. The sum is 2n, where n is the number of bits used for representing the signed integer. That is, the sum is one followed by n zeroes. The one gets recorded in the CF. Since the CF is irrelevant in two’s complement arithmetic, the result — n zeroes — is correct.

In two’s complement, zero does not have a representation of opposite sign. (-0.0 does exist in IEEE 754 ﬂoating point.) Also, 2n1 does not have a representation of opposite sign.

3 -7

a) +85 b) -86 c) -16 d) +15 e) -128 f) +99 g) +123

3 -8

a) +4660 b) -4660 c) -292 d) +2000 e) -32768 f) +1024 g) -1 h) +30767

3 -9

a) 64 b) ff c) f6 d) 58 e) 7f f) f0 g) e0 h) 80

3 -10

a) 0400 b) fc00 c) ffff d) 7fff e) ff00 f) 8000 g) 8001 h) ff80
3 -11

a) ff
CF = 0 unsigned right
OF = 0 signed right b) 45
CF = 1 unsigned wrong
OF = 0 signed right c) fb
CF = 0 unsigned right
OF = 0 signed right d) de
CF = 0 unsigned right
OF = 1 signed wrong e) 0e
CF = 1 unsigned wrong
OF = 0 signed right f) 00
CF = 1 unsigned wrong
OF = 1 signed wrong
3 -12

a) 0000
CF = 1 unsigned wrong
OF = 0 signed right b) 1110
CF = 1 unsigned wrong
OF = 0 signed right c) 0000
CF = 1 unsigned wrong
OF = 1 signed wrong d) 03ff
CF = 1 unsigned wrong
OF = 0 signed right e) 7fff
CF = 0 unsigned right
OF = 0 signed right f) 7fff
CF = 1 unsigned wrong
OF = 1 signed wrong
3 -14

1/*
2 * hexTimesTen.c
3 * Multiplies a hex number by 10.
4 * Bob Plantz - 19 June 2009
5 */
6
8#include "writeStr.h"
9#include "hex2int.h"
10#include "int2hex.h"
11
12int main(void)
13{
14    char aString[9];
15    unsigned int x;
16
17    writeStr("Enter a hex number: ");
19    x = hex2int(aString);
20    x *= 10;
21    int2hex(aString, x);
22    writeStr("Multiplying by ten gives: ");
23    writeStr(aString);
24    writeStr("\n");
25
26    return 0;
27}

1/*
2 * hex2int.h
3 *
4 * Converts a hexadecimal text string to corresponding
5 * unsigned int format.
6 * Assumes text string is valid hex chars.
7 *
8 * input:
9 *    pointer to null-terminated text string
10 * output:
11 *    returns the unsigned int.
12 *
13 * Bob Plantz - 19 June 2009
14 */
15
16#ifndef HEX2INT_H
17#define HEX2INT_H
18
19unsigned int hex2int(char *hexString);
20
21#endif

1/*
2 * hex2int.c
3 *
4 * Converts a hexadecimal text string to corresponding
5 * unsigned int format.
6 * Assumes text string is valid hex chars.
7 *
8 * input:
9 *    pointer to null-terminated text string
10 * output:
11 *    returns the unsigned int.
12 *
13 * Bob Plantz - 19 June 2009
14 */
15
16#include "hex2int.h"
17
18unsigned int hex2int(char *hexString)
19{
20    unsigned int x;
21    unsigned char aChar;
22
23    x = 0;                      // initialize result
24    while (*hexString != \0)  // end of string?
25    {
26        x = x << 4;             // make room for next four bits
27        aChar = *hexString;
28        if (aChar <= 9)
29            x = x + (aChar & 0x0f);
30        else
31        {
32            aChar = aChar & 0x0f;
33            aChar = aChar + 9;
34            x = x + aChar;
35        }
36        hexString++;
37    }
38
39    return x;
40}

1/*
2 * int2hex.h
3 *
4 * Converts an unsigned int to corresponding
5 * hex text string format.
6 * Assumes char array is big enough.
7 *
8 * input:
9 *    unsigned int
10 * output:
11 *    null-terminated text string
12 *
13 * Bob Plantz - 19 June 2009
14 */
15
16#ifndef INT2HEX_H
17#define INT2HEX_H
18
19void int2hex(char *hexString, unsigned int number);
20
21#endif

1/*
2 * int2hex.c
3 *
4 * Converts an unsigned int to corresponding
5 * hex text string format.
6 * Assumes char array is big enough.
7 *
8 * input:
9 *    unsigned int
10 * output:
11 *    null-terminated text string
12 *
13 * Bob Plantz - 19 June 2009
14 */
15
16#include "int2hex.h"
17
18void int2hex(char *hexString, unsigned int number)
19{
20    unsigned char aChar;
21    int i;
22
23    hexString[8] = \0;        // install string terminator
24    for (i = 7; i >= 0; i--)
25    {
26        aChar = number & 0x0f;  // get four bits
27        if (aChar <= 9)
28            aChar += 0;
29        else
30            aChar = aChar - 10 + a;
31        hexString[i] = aChar;
32        number = number >> 4;
33    }
34}

See Section E.2 for writeStr and readLn.

3 -15

1/*
2 * binTimesTen.c
3 * Multiplies a hex number by 10.
4 *
5 * Bob Plantz - 19 June 2009
6 */
7
9#include "writeStr.h"
10#include "bin2int.h"
11#include "int2bin.h"
12
13int main(void)
14{
15    char aString[33];
16    unsigned int x;
17
18    writeStr("Enter a binary number: ");
20    x = bin2int(aString);
21    x *= 10;
22    int2bin(aString, x);
23    writeStr("Multiplying by ten gives: ");
24    writeStr(aString);
25    writeStr("\n");
26
27    return 0;
28}

1/*
2 * bin2int.h
3 *
4 * bin2int.c
5 * Converts a binary text string to corresponding
6 * unsigned int format.
7 * Assumes text string contains valid binary chars.
8 *
9 * input:
10 *    pointer to null-terminated text string
11 * output:
12 *    returns the unsigned int.
13 *
14 * Bob Plantz - 19 June 2009
15 */
16
17#ifndef BIN2INT_H
18#define BIN2INT_H
19
20unsigned int bin2int(char *binString);
21
22#endif

1/*
2 * bin2int.c
3 * Converts a binary text string to corresponding
4 * unsigned int format.
5 * Assumes text string contains valid binary chars.
6 *
7 * input:
8 *    pointer to null-terminated text string
9 * output:
10 *    returns the unsigned int.
11 *
12 * Bob Plantz - 19 June 2009
13 */
14
15#include "bin2int.h"
16
17unsigned int bin2int(char *binString)
18{
19    unsigned int x;
20    unsigned char aChar;
21
22    x = 0;                      // initialize result
23    while (*binString != \0)  // end of string?
24    {
25        x = x << 1;             // make room for next bit
26        aChar = *binString;
27        x |= (0x1 & aChar);     // sift out the bit
28        binString++;
29    }
30
31    return x;
32}

1/*
2 * int2bin.h
3 *
4 * Converts an unsigned int to corresponding
5 * binary text string format.
6 * Assumes char array is big enough.
7 *
8 * input:
9 *    unsigned int
10 * output:
11 *    null-terminated text string
12 *
13 * Bob Plantz - 19 June 2009
14 */
15
16#ifndef INT2BIN_H
17#define INT2BIN_H
18
19void int2bin(char *binString, unsigned int number);
20
21#endif

1/*
2 * int2bin.c
3 *
4 * Converts an unsigned int to corresponding
5 * binary text string format.
6 * Assumes char array is big enough.
7 *
8 * input:
9 *    unsigned int
10 * output:
11 *    null-terminated text string
12 *
13 * Bob Plantz - 19 June 2009
14 */
15
16#include "int2bin.h"
17
18void int2bin(char *binString, unsigned int number)
19{
20    int i;
21
22    binString[32] = \0;      // install string terminator
23    for (i = 31; i >= 0; i--)
24    {
25        if (number & 0x01)
26            binString[i] = 1;
27        else
28            binString[i] = 0;
29        number = number >> 1;
30    }
31}

See Section E.2 for writeStr and readLn.

3 -16

1/*
2 * uDecTimesTen.c
3 * Multiplies a decimal number by 10.
4 * Bob Plantz - 20 June 1009
5 */
6
8#include "writeStr.h"
9#include "udec2int.h"
10#include "int2bin.h"
11
12int main(void)
13{
14    char aString[33];
15    unsigned int x;
16
17    writeStr("Enter a decimal number: ");
19    x = udec2int(aString);
20    x *= 10;
21    int2bin(aString, x);
22    writeStr("Multiplying by ten gives (in binary): ");
23    writeStr(aString);
24    writeStr("\n");
25
26    return 0;
27}

1/*
2 * uDec2int.h
3 *
4 * Converts a decimal text string to corresponding
5 * unsigned int format.
6 * Assumes text string is valid decimal chars.
7 *
8 * input:
9 *    pointer to null-terminated text string
10 * output:
11 *    returns the unsigned int.
12 *
13 * Bob Plantz - 19 June 2009
14 */
15
16#ifndef UDEC2INT_H
17#define UDEC2INT_H
18
19unsigned int uDec2int(char *decString);
20
21#endif

1/*
2 * uDec2int.c
3 *
4 * Converts a decimal text string to corresponding
5 * unsigned int format.
6 * Assumes text string is valid decimal chars.
7 *
8 * input:
9 *    pointer to null-terminated text string
10 * output:
11 *    returns the unsigned int.
12 *
13 * Bob Plantz - 19 June 2009
14 */
15
16#include "uDec2int.h"
17
18unsigned int uDec2int(char *decString)
19{
20    unsigned int x;
21    unsigned char aChar;
22
23    x = 0;                       // initialize result
24    while (*decString != \0)   // end of string?
25    {
26        x *= 10;
27        aChar = *decString;
28        x += (0xf & aChar);
29        decString++;
30    }
31
32    return x;
33}

See above for int2bin. See Section E.2 for writeStr and readLn.

3 -17

1/*
2 * sDecTimesTen.c
3 * Multiplies a signed decimal number by 10
4 * and shows result in binary.
5 * Bob Plantz - 21 June 2009
6 */
7
9#include "writeStr.h"
10#include "sDec2int.h"
11#include "int2bin.h"
12
13int main(void)
14{
15    char aString[33];
16    int x;
17
18    writeStr("Enter a signed decimal number: ");
20    x = sDec2int(aString);
21    x *= 10;
22    int2bin(aString, x);
23    writeStr("Multiplying by ten gives (in binary): ");
24    writeStr(aString);
25    writeStr("\n");
26
27    return 0;
28}

1/*
2 * sDec2int.h
3 *
4 * Converts a decimal text string to corresponding
5 * signed int format.
6 * Assumes text string is valid decimal chars.
7 *
8 * input:
9 *    pointer to null-terminated text string
10 * output:
11 *    returns the signed int.
12 *
13 * Bob Plantz - 19 June 2009
14 */
15
16#ifndef SDEC2INT_H
17#define SDEC2INT_H
18
19int sDec2int(char *decString);
20
21#endif

1/*
2 * sDec2int.c
3 *
4 * Converts a decimal text string to corresponding
5 * signed int format.
6 * Assumes text string is valid decimal chars.
7 *
8 * input:
9 *    pointer to null-terminated text string
10 * output:
11 *    returns the signed int.
12 *
13 * Bob Plantz - 19 June 2009
14 */
15
16#include "uDec2int.h"
17#include "sDec2int.h"
18
19int sDec2int(char *decString)
20{
21    int x;
22    int negative = 0;
23
24    if (*decString == -)
25    {
26       negative = 1;
27       decString++;
28    }
29    else
30    {
31        if (*decString == +)
32            decString++;
33    }
34
35    x = uDec2int(decString);
36
37    if (negative)
38       x *= -1;
39
40    return x;
41}

See above for int2bin and uDec2int. See Section E.2 for writeStr and readLn.

E.4 Logic Gates

4 -1

Using truth tables:

 x x ⋅ 1 0 1 0 1 1 1

 x x + 0 0 0 0 1 0 1

4 -2

Using truth tables:

 x y x ⋅ y y ⋅ x 0 0 0 0 0 1 0 0 1 0 0 0 1 1 1 1

 x y x + y y + x 0 0 0 0 0 1 1 1 1 0 1 1 1 1 1 1

4 -3

Using truth tables:

 x x ⋅ 0 0 0 0 1 0 0

 x x + 1 0 1 1 1 1 1

4 -4

Using truth tables:

 x x′ x ⋅ 0 0 1 0 1 0 0

 x x′ x + 1 0 1 1 1 0 1

4 -5

Using truth tables:

 x x x ⋅ 0 0 0 0 1 1 1

 x x x + 1 0 0 0 1 1 1

4 -6

Using truth tables:

 x y z x ⋅ (y + z) x ⋅ y + x ⋅ z 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 1 1 0 0 1 0 0 0 0 1 0 1 1 1 1 1 0 1 1 1 1 1 1 1

 x y z x + y ⋅ z (x + y) ⋅ (x + z) 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 1 1 1 1 1 0 0 1 1 1 0 1 1 1 1 1 0 1 1 1 1 1 1 1

4 -7

Using a truth table and letting y = x:

 x y = x′ y′ 0 1 0 1 0 1
4 -9

Minterms:

4 -10

Minterms:

4 -11

The prime numbers correspond to the minterms m2, m3, m5, and m7. The minterms m10, m11, m12, m13, m14, m15 cannot occur so are marked “don’t care” on the Karnaugh map.

4 -15

2-bit “below” circuit.

 x1 x0 y1 y0 F 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

E.5 Logic Circuits

5 -3

Referring to Figure 5.27 (page 402), we see that JK = 10 is the set (state = 1) input and JK = 01 is the reset (state = 0).

 Enable = 0 Enable = 1 Current Next Next n1 n0 n1 n0 J1 K1 J0 K0 n1 n0 J1 K1 J0 K0 0 0 0 0 0 1 0 1 0 1 0 1 1 0 0 1 0 1 0 1 1 0 1 0 1 0 0 1 1 0 1 0 1 0 0 1 1 1 1 0 1 0 1 1 1 1 1 0 1 0 0 0 0 1 0 1

This leads to the following equations for the inputs to the JK ﬂip-ﬂops (using “E” for “Enable”):

Simplify these equations using Karnaugh maps.

5 -4

Four-bit up counter.

E.6 Central Processing Unit

6 -3

The compiler will not use a register for the theInteger variable because the algorithm requires the address of this variable, and registers have no memory address.

6 -5

1/*
2 * endian.c
3 * Determines endianess. If endianess cannot be determined
4 * from input value, defaults to "big endian"
5 * Bob Plantz - 22 June 2009
6 */
7
8#include <stdio.h>
9
10int main(void)
11{
12    unsigned char *ptr;
13    int x, i, bigEndian;
14
15    ptr = (unsigned char *)&x;
16
17    printf("Enter a non-zero integer: ");
18    scanf("%i", &x);
19
20    printf("You entered %#010x and it is stored\n", x);
21    for (i = 0; i < 4; i++)
22        printf("   %p: %02x\n", ptr + i, *(ptr + i));
23
24    bigEndian = (*ptr == (unsigned char)(0xff & (x >> 24))) &&
25            (*(ptr + 1) == (unsigned char)(0xff & (x >> 16))) &&
26            (*(ptr + 2) == (unsigned char)(0xff & (x >> 8))) &&
27            (*(ptr + 3) == (unsigned char)(0xff & x));
28    if (bigEndian)
29        printf("which is big endian.\n");
30    else
31        printf("which is little endian.\n");
32
33    return 0;
34}
6 -6

1/*
2 * endianReg.c
3 * Stores user int in memory then copies to register var.
4 * Use gdb to observe endianess.
5 * Bob Plantz - 22 June 2009
6 */
7
8#include <stdio.h>
9
10int main(void)
11{
12    int x;
13    register int y;
14
15    printf("Enter an integer: ");
16    scanf("%i", &x);
17
18    y = x;
19    printf("You entered %i\n", y);
20
21    return 0;
22}

When I ran this program with the input -1985229329, I got the results:

(gdb) print &x
\$5 = (int *) 0x7ffff74f473c
(gdb) x/4xb 0x7ffff74f473c
0x7ffff74f473c: 0xef 0xcd 0xab 0x89
(gdb) i r rcx
rcx            0xffffffff89abcdef -1985229329
(gdb) print x
\$6 = -1985229329
(gdb)

which shows the value stored in rcx (used as the y variable) is in regular order, and the value store in memory (the x variable) is in little endian.

E.7 Programming in Assembly Language

7 -1

1# f.s
2# Does nothing but return zero to caller.
3# Bob Plantz - 22 June 2009
4
5        .text
6        .globl  f
7        .type   f, @function
8f:
9        pushq   %rbp            # save callers frame pointer
10        movq    %rsp, %rbp      # establish ours
11
12        movl    \$0, %eax        # return 0;
13
14        movq    %rbp, %rsp      # delete local vars.
15        popq    %rbp            # restore callers frame pointer
16        ret                     # return to caller
7 -2

1# g.s
2# Does nothing but return to caller.
3# Bob Plantz - 22 June 2009
4
5        .text
6        .globl  g
7        .type   g, @function
8g:
9        pushq   %rbp            # save callers frame pointer
10        movq    %rsp, %rbp      # establish ours
11
12# A function that returns void has "garbage" in eax.
13
14        movq    %rbp, %rsp      # delete local vars.
15        popq    %rbp            # restore callers frame pointer
16        ret                     # return to caller
7 -3

1# h.s
2# Does nothing but return 123 to caller.
3# Bob Plantz - 22 June 2009
4
5        .text
6        .globl  h
7        .type   h, @function
8h:
9        pushq   %rbp            # save callers frame pointer
10        movq    %rsp, %rbp      # establish ours
11
12        movl    \$123, %eax      # return 123;
13
14        movq    %rbp, %rsp      # delete local vars.
15        popq    %rbp            # restore callers frame pointer
16        ret                     # return to caller
7 -4

1/*
2 * checkRetNos.c
3 * calls three assembly language functions and
4 * prints their return numbers.
5 *
6 * Bob Plantz - 22 June 2009
7 */
8
9#include <stdio.h>
10int one();
11int two();
12int three();
13
14int main()
15{
16    int x;
17
18    x = one();
19    printf("one returns %i, ", x);
20
21    x = two();
22    printf("two returns %i, and ", x);
23
24    x = three();
25    printf("three returns %i.\n", x);
26
27    return 0;
28}

1# one.s
2# returns 1 to calling function.
3# Bob Plantz - 22 June 2009
4
5        .text
6        .globl  one
7        .type   one, @function
8one:
9        pushq   %rbp            # save callers base pointer
10        movq    %rsp, %rbp      # establish ours
11
12        movl    \$1, %eax        # return 1;
13
14        movq    %rbp, %rsp      # delete local vars.
15        popq    %rbp            # restore callers base pointer
16        ret                     # return to caller

1# two.s
2# returns 2 to calling function.
3# Bob Plantz - 22 June 2009
4
5        .text
6        .globl  two
7        .type   two, @function
8two:
9        pushq   %rbp            # save callers base pointer
10        movq    %rsp, %rbp      # establish ours
11
12        movl    \$2, %eax        # return 1;
13
14        movq    %rbp, %rsp      # delete local vars.
15        popq    %rbp            # restore callers base pointer
16        ret                     # return to caller

1# three.s
2# returns 3 to calling function.
3# Bob Plantz - 22 June 2009
4
5        .text
6        .globl  three
7        .type   three, @function
8three:
9        pushq   %rbp            # save callers base pointer
10        movq    %rsp, %rbp      # establish ours
11
12        movl    \$3, %eax        # return 3;
13
14        movq    %rbp, %rsp      # delete local vars.
15        popq    %rbp            # restore callers base pointer
16        ret                     # return to caller
7 -5

1/*
2 * checkRetLtrs.c
3 * calls three assembly language functions and
4 * prints their return characters.
5 *
6 * Bob Plantz - 22 June 2009
7 */
8
9#include <stdio.h>
10char el();
11char em();
12char en();
13
14int main()
15{
16    char letter;
17
18    letter = el();
19    printf("el returns %c, ", letter);
20
21    letter = em();
22    printf("en returns %c, and ", letter);
23
24    letter = en();
25    printf("em returns %c.\n", letter);
26
27    return 0;
28}

1# el.s
2# returns L to calling function.
3# Bob Plantz - 22 June 2009
4        .text
5        .globl  el
6        .type   el, @function
7el:
8        pushq   %rbp            # save callers base pointer
9        movq    %rsp, %rbp      # establish ours
10
11        movl    \$L, %eax       # return L;
12
13        movq    %rbp, %rsp      # delete local vars.
14        popq    %rbp            # restore callers base pointer
15        ret                     # return to caller

1# em.s
2# returns M to calling function.
3# Bob Plantz - 22 June 2009
4        .text
5        .globl  em
6        .type   em, @function
7em:
8        pushq   %rbp            # save callers base pointer
9        movq    %rsp, %rbp      # establish ours
10
11        movl    \$M, %eax       # return M;
12
13        movq    %rbp, %rsp      # delete local vars.
14        popq    %rbp            # restore callers base pointer
15        ret                     # return to caller

1# en.s
2# returns N to calling function.
3# Bob Plantz - 22 June 2009
4        .text
5        .globl  en
6        .type   en, @function
7en:
8        pushq   %rbp            # save callers base pointer
9        movq    %rsp, %rbp      # establish ours
10
11        movl    \$N, %eax       # return N;
12
13        movq    %rbp, %rsp      # delete local vars.
14        popq    %rbp            # restore callers base pointer
15        ret                     # return to caller
7 -6

The four characters are returned as a 4-byte word and then stored in memory by main. They are then written to standard out one character at a time. Storage order in memory is little endian, so the characters are displayed “backwards.”

1/*
2 * fourLetterWord.c
3 * calls a function to get a four letter word, then
4 * prints it.
5 *
6 * Bob Plantz - 22 June 2009
7 */
8
9#include <unistd.h>
10#include "retWord.h"
11
12int main()
13{
14    int x;
15    char endl = \n;
16
17    x = retWord();
18    write(STDOUT_FILENO, &x, 4);
19
20    write(STDOUT_FILENO, &endl, 1);
21
22    return 0;
23}

1# retWord.s
2# returns 4-letter word to calling function.
3# Bob Plantz - 22 June 2009
4        .text
5        .globl  retWord
6        .type   retWord, @function
7retWord:
8        pushq   %rbp            # save callers base pointer
9        movq    %rsp, %rbp      # establish ours
10
11        movl    \$0x61426339, %eax        # return "aBc9";
12
13        movq    %rbp, %rsp      # delete local vars.
14        popq    %rbp            # restore callers base pointer
15        ret                     # return to caller

E.8 Program Data – Input, Store, Output

8 -2

1/*
2 * stackPositive.c
3 * implementation of push and pop stack operations in C
4 *
5 * Bob Plantz - 22 June 2009
6 */
7
8#include <stdio.h>
9
10int theStack[500];
11int *stackPointer = &theStack[0];
12
13/*
14 * precondition:
15 *     stackPointer points to data element at top of stack
16 * postcondtion:
17 *     address in stackPointer is incremented by four
18 *     data_value is stored at top of stack
19 */
20void push(int data_value)
21{
22    stackPointer++;
23    *stackPointer = data_value;
24}
25
26/*
27 * precondition:
28 *     stackPointer points to data element at top of stack
29 * postcondtion:
30 *     data element at top of stack is copied to *data_location
31 *     address in stackPointer is decremented by four
32 */
33void pop(int *data_location)
34{
35    *data_location = *stackPointer;
36    stackPointer--;
37}
38
39int main(void)
40{
41    int x = 12;
42    int y = 34;
43    int z = 56;
44    printf("Start with the stack pointer at %p", (void *)stackPointer);
45    printf(", and x = %i, y = %i, and z = %i\n", x, y, z);
46
47    push(x);
48    push(y);
49    push(z);
50    x = 100;
51    y = 200;
52    z = 300;
53    printf("Now the stack pointer is at %p", (void *)stackPointer);
54    printf(", and x = %i, y = %i, and z = %i\n", x, y, z);
55    pop(&z);
56    pop(&y);
57    pop(&x);
58
59    printf("And we end with the stack pointer at %p", (void *)stackPointer);
60    printf(", and x = %i, y = %i, and z = %i\n", x, y, z);
61
62    return 0;
63}
8 -3

Use gdb to examine the values in the rbp and rsp registers just before the ﬁrst and just before the last instructions are executed.

8 -4

This exercise shows that the text strings and local variables are stored in diﬀerent areas of memory.

8 -6

1# int2hex.s
2# Prompts user to enter an integer, then displays its hex equivalent
3# Bob Plantz - 22 June 2009
4
5# Stack frame
6        .equ    anInt,-4
7        .equ    localSize,-16
9        .section  .rodata
10prompt:
11        .string "Enter an integer number: "
12scanFormat:
13        .string "%i"
14printFormat:
15        .string "%i = %x\n"
16# Code
17        .text                  # switch to text segment
18        .globl  main
19        .type   main, @function
20main:
21        pushq   %rbp           # save callers base pointer
22        movq    %rsp, %rbp     # establish our base pointer
23        addq    \$localSize, %rsp  # for local variable
24
25        movl    \$prompt, %edi  # address of prompt text string
26        movl    \$0, %eax       # no floating point args.
27        call    printf         # invoke printf function
28
29        leaq    anInt(%rbp), %rsi  # place to store integer
30        movl    \$scanFormat, %edi  # address of scanf format string
31        movl    \$0, %eax       # no floating point args.
32        call    scanf          # invoke scanf function
33
34        movl    anInt(%rbp), %edx   # the integer
35        movl    anInt(%rbp), %esi   #    two copies
36        movl    \$printFormat, %edi  # address of printf text string
37        movl    \$0, %eax       # no floating point args.
38        call    printf         # invoke printf function
39
40        movl    \$0, %eax       # return 0
41        movq    %rbp, %rsp     # delete local variables
42        popq    %rbp           # restore callers base pointer
43        ret                    # back to calling function
8 -7

1# assignSeveral.s
2# Assigns values to four chars and four ints and prints them.
3# Bob Plantz - 22 June 2009
4
5# Stack frame
6        .equ    a,-1
7        .equ    b,-2
8        .equ    c,-3
9        .equ    d,-4
10        .equ    w,-8
11        .equ    x,-12
12        .equ    y,-16
13        .equ    z,-20
14        .equ    arg7,0
15        .equ    arg8,8
16        .equ    arg9,16
17        .equ    localSize,-48
19        .section  .rodata
20format:
21        .string "The values are %c, %i, %c, %i, %c, %i, %c, and %i\n"
22# Code
23       .text
24       .globl  main
25       .type   main, @function
26main:
27        pushq   %rbp             # save calling functions base pointer
28        movq    %rsp, %rbp       # establish our base pointer
29        addq    \$localSize, %rsp # allocate memory for local variables
30
31        movb    \$A, a(%rbp)    # initialize chars
32        movb    \$B, b(%rbp)
33        movb    \$C, c(%rbp)
34        movb    \$D, d(%rbp)
35        movl    \$12, w(%rbp)     # and ints
36        movl    \$34, x(%rbp)
37        movl    \$45, y(%rbp)
38        movl    \$67, z(%rbp)
39
40        movslq  z(%rbp), %rax    # load z
41        movq    %rax, arg9(%rsp) # and place on stack
42        movzbq  d(%rbp), %rax    # load d
43        movq    %rax, arg8(%rsp) # place on stack
44        movslq  y(%rbp), %rax    # load y
45        movq    %rax, arg7(%rsp) # place on stack
46        movl    y(%rbp), %r9d
47        movzblc(%rbp), %r9d    # load args into regs.
48        movl    x(%rbp), %r8d
49        movzblb(%rbp), %ecx
50        movl    w(%rbp), %edx
51        movzbla(%rbp), %esi
52        movl    \$format, %edi    # format string
53        movl  \$0, %eax         # no floating point values
54        call  printf
55
56        movq    %rbp, %rsp       # delete local variables
57        popq    %rbp             # restore calling functions base pointer
58        movl    \$0, %eax         # return 0
59        ret

E.9 Computer Operations

9 -1

 instruction n bytes rax rsi rbp rsp 7f940f088a60 7ﬀf24330778 0 7ﬀf172a9618 pushq %rbp 1 7f940f088a60 7ﬀf24330778 0 7ﬀf172a9610 movl %rsp, %rbp 3 7f940f088a60 7ﬀf24330778 7ﬀf172a9610 7ﬀf172a9610 movl \$0xabcd1234,%esi 5 7f940f088a60 abcd1234 7ﬀf172a9610 7ﬀf172a9610 movl \$0, %eax 5 0 abcd1234 7ﬀf172a9610 7ﬀf172a9610 movl %rbp, %rsp 3 0 abcd1234 7ﬀf172a9610 7ﬀf172a9610 popq %rbp 1 0 abcd1234 0 7ﬀf172a9618 ret
9 -3

2        .section      .rodata
3.LC0:
4        .string"Enter two integers: "
5.LC1:
6        .string"%i %i"
7.LC2:
8        .string"sum = %i, difference = %i\n"
9        .text
10        .globlmain
11        .type  main, @function
12main:
13        pushq  %rbp
14        movq  %rsp, %rbp
15        subq  \$16, %rsp
16        movl  \$.LC0, %edi
17        movl  \$0, %eax
18        call  printf
19        leaq  -12(%rbp), %rdx
20        leaq  -16(%rbp), %rax
21        movq  %rax, %rsi
22        movl  \$.LC1, %edi
23        movl  \$0, %eax
24        call  __isoc99_scanf
25        movl  -16(%rbp), %eax   # load w
26        movl  %eax, -8(%rbp)    # y = w;
27        movl  -12(%rbp), %eax   # load x
28        addl  %eax, -8(%rbp)    # y += x;
29        movl  -16(%rbp), %eax   # load w
30        movl  %eax, -4(%rbp)    # z = w;
31        movl  -12(%rbp), %eax   # load x
32        subl  %eax, -4(%rbp)    # z -= x;
33        movl  -4(%rbp), %edx
34        movl  -8(%rbp), %eax
35        movl  %eax, %esi
36        movl  \$.LC2, %edi
37        movl  \$0, %eax
38        call  printf
39        movl  \$0, %eax
40        leave
41        ret
42        .size  main, .-main
43        .ident"GCC: (Ubuntu/Linaro 4.7.0-7ubuntu3) 4.7.0"
44        .section      .note.GNU-stack,"",@progbits
9 -4

The assembly language program in Listing 9.6 uses esi for the y variable and edx for the z variable. If there is overﬂow, the call to printf changes the contents of these registers. So when the results are displayed y and/or z are incorrect.

2# Gets two integers from user, then
4# Bob Plantz - 23 June 2009
5# Stack frame
6        .equ    w,-16
7        .equ    x,-12
8        .equ    y,-8
9        .equ    z,-4
10        .equ    localSize,-16
12        .section  .rodata
13prompt:
14        .string "Enter two integers: "
15getData:
16        .string "%i %i"
17display:
18        .string "sum = %i, difference = %i\n"
19warning:
20        .string "Overflow has occurred.\n"
21# Code
22        .text
23        .globl  main
24        .type   main, @function
25main:
26        pushq   %rbp        # save callers base pointer
27        movq    %rsp, %rbp  # establish our base pointer
28        addq    \$localSize, %rsp  # for local vars
29
30        movl    \$prompt, %edi  # prompt user
31        movl    \$0, %eax       # no floats
32        call    printf
33
34        leaq    x(%rbp), %rdx  # &x
35        leaq    w(%rbp), %rsi  # &w
36        movl    \$getData, %edi # get user data
37        movl    \$0, %eax       # no floats
38        call    scanf
39
40##############################################################
41# These three instructions could replace the four that follow
42# this sequence. They work because mov does not affect eflags.
43# But changes in the code may introduce an instruction before
44# the jno that does affect eflags, thus breaking the code.
45#       movl    w(%rbp), %eax  # load w
47#       movl    %eax, y(%rbp)  # y = w + x
48##############################################################
49        movl    w(%rbp), %eax  # load w
50        movl    %eax, y(%rbp)  # y = w
51        movl    x(%rbp), %eax  # load x
52        addl    %eax, y(%rbp)  # y = w + x
53        jno     nOver1         # skip warning if no OF
54        movl    \$warning, %edi #### changes edi
55        movl    \$0, %eax
56        call    printf         #### may change several registers
57nOver1:
58        movl    w(%rbp), %eax  # load w
59        movl    %eax, z(%rbp)  # z = w
60        movl    x(%rbp), %eax  # load x
61        subl    %eax, z(%rbp)  # z = w - x
62        jno     nOver2         # skip warning if no OF
63        movl    \$warning, %edi
64        movl    \$0, %eax
65        call    printf
66nOver2:
67        movl    z(%rbp), %edx  # load z
68        movl    y(%rbp), %esi  # and y
69        movl    \$display, %edi # display results
70        movl    \$0, %eax       # no floats
71        call    printf
72
73        movl    \$0, %eax       # return 0 to OS
74        movq    %rbp, %rsp     # restore stack pointer
75        popq    %rbp           # restore callers base pointer
76        ret
9 -7

GAS LISTING Exercise_9-6.s  page 1

1               # Exercise_9-6.s
2               # This is not a program. It is a group of
3               # instructions to hand-assemble.
4               # Bob Plantz - 27 June 2009
5                       .text
6                       .globl  main
7               main:
8 0000 55                pushq   %rbp
9 0001 4889E5            movq    %rsp, %rbp
10
11 0004 B9EFCDAB          movl    \$0x89abcdef, %ecx     # a)
11      89
12 0009 66B8CDAB          movw    \$0xabcd, %ax          # b)
13 000d B030              movb    \$0x30, %al            # c)
14 000f B431              movb    \$0x31, %ah            # d)
15 0011 4D89C7            movq    %r8, %r15             # e)
16 0014 4588CA            movb    %r9b, %r10b           # f)
17 0017 4589DC            movl    %r11d, %r12d          # g)
18 001a 48BEF42C          movq    \$0x7fffec9b2cf4, %rsi # h)
18      9BECFF7F
18      0000
19
20 0024 B8000000          movl    \$0, %eax
20      00
21 0029 4889EC            movq    %rbp, %rsp
22 002c 5D                popq    %rbp
23 002d C3                ret
24
_______________________________________________________________________________

9 -8

GAS LISTING Exercise_9-7.s  page 1

1               # Exercise_9-7.s
2               # This is not a program. It is a group of
3               # instructions to hand-assemble.
4               # Bob Plantz - 27 June 2009
5                       .text
6                       .globl  main
7               main:
8 0000 55                pushq   %rbp
9 0001 4889E5            movq    %rsp, %rbp
10
11 0004 81C1EFCD          addl    \$0x89abcdef, %ecx  # a)
11      AB89
12 000a 6605CDAB          addw    \$0xabcd, %ax       # b)
13 000e 0430              addb    \$0x30, %al         # c)
14 0010 80C431            addb    \$0x31, %ah         # d)
15 0013 4D01E7            addq    %r12, %r15         # e)
16 0016 664501C2          addw    %r8w, %r10w        # f)
17 001a 4400CE            addb    %r9b, %sil         # g)
18 001d 01F7              addl    %esi, %edi         # h)
19
20 001f B8000000          movl    \$0, %eax
20      00
21 0024 4889EC            movq    %rbp, %rsp
22 0027 5D                popq    %rbp
23 0028 C3                ret
24
_______________________________________________________________________________
9 -9

GAS LISTING Exercise_9-8.s  page 1

1               # Exercise_9-8.s
2               # This is not a program. It is an experiment
3               # to determine the machine code for pushl.
4               # Bob Plantz - 27 June 2009
5                       .text
6                       .globl  main
7               main:
8 0000 55                pushq   %rbp
9 0001 4889E5            movq    %rsp, %rbp
10
11 0004 50        pushq   %rax
12 0005 51                pushq   %rcx
13 0006 52                pushq   %rdx
14 0007 53                pushq   %rbx
15 0008 56                pushq   %rsi
16 0009 57                pushq   %rdi
17 000a 4150              pushq   %r8
18 000c 4151              pushq   %r9
19 000e 4152              pushq   %r10
20 0010 4153              pushq   %r11
21 0012 4154              pushq   %r12
22 0014 4155              pushq   %r13
23 0016 4156              pushq   %r14
24 0018 4157              pushq   %r15
25
26 001a 415F              popq    %r15
27 001c 415E              popq    %r14
28 001e 415D              popq    %r13
29 0020 415C              popq    %r12
30 0022 415B              popq    %r11
31 0024 415A              popq    %r10
32 0026 4159              popq    %r9
33 0028 4158              popq    %r8
34 002a 5F                popq    %rdi
35 002b 5E                popq    %rsi
36 002c 5B                popq    %rbx
37 002d 5A                popq    %rdx
38 002e 59                popq    %rcx
39 002f 58        popq    %rax
40
41 0030 B8000000          movl    \$0, %eax
41      00
42 0035 4889EC            movq    %rbp, %rsp
43 0038 5D                popq    %rbp
44 0039 C3                ret
45
_______________________________________________________________________________
9 -10

See solution to Exercise 9

9 -11

GAS LISTING Exercise_9-10.s  page 1

1               # Exercise_9-10.s
2               # This is not a program. I used the machine code from the
3               # listing to create Exercise 9-9.
4               # Uses a drill and kill approach to learning
5               # how to disassemble machine code
6               # Bob Plantz - 27 June 2009
7                       .text
8                       .globl  main
9               main:
10 0000 55                pushq   %rbp
11 0001 4889E5            movq    %rsp, %rbp
12
13               #a
14 0004 B0AB              movb    \$0xab, %al
15 0006 B4CD              movb    \$0xcd, %ah
16 0008 41B0EF            movb    \$0xef, %r8b
17 000b 41B701            movb    \$0x01, %r15b
18
19               #b
20 000e 40B723            movb    \$0x23, %dil
21 0011 40B634            movb    \$0x34, %sil
22 0014 B256              movb    \$0x56, %dl
23 0016 B678              movb    \$0x78, %dh
24
25               #c
26 0018 B83412CD          movl    \$0xabcd1234, %eax
26      AB
27 001d BBABCD12          movl    \$0x3412cdab, %ebx
27      34
28 0022 41B90000          movl    \$0x0, %r9d
28      0000
29 0028 41BE7B00          movl    \$0x7b, %r14d
29      0000
30
31               #d
32 002e 66B8CDAB          movw    \$0xabcd, %ax
33 0032 66BBBACD          movw    \$0xcdba, %bx
34 0036 66B93412          movw    \$0x1234, %cx
35 003a 66BA2143          movw    \$0x4321, %dx
36
37               #e
38 003e 88C4              movb    %al, %ah
39 0040 88C8              movb    %cl, %al
40 0042 8808              movb    %cl, (%rax)
41 0044 88480A            movb    %cl, 10(%rax)
42 0047 8A08              movb    (%rax), %cl
43 0049 8A480A            movb    10(%rax), %cl
44
45               #f
46 004c 89C3              movl    %eax, %ebx
47 004e 6689D8            movw    %bx, %ax
48 0051 4889CA            movq    %rcx, %rdx
49 0054 4589C6            movl    %r8d, %r14d
50
51               #g
52 0057 04AB              addb    \$0xab, %al
53 0059 80C4CD            addb    \$0xcd, %ah
GAS LISTING Exercise_9-10.s  page 2

54 005c 80C3EF            addb    \$0xef, %bl
55 005f 80C701            addb    \$0x01, %bh
56
57               #h
58 0062 80C123            addb    \$0x23, %cl
59 0065 80C534            addb    \$0x34, %ch
60 0068 80C256            addb    \$0x56, %dl
61 006b 80C678            addb    \$0x78, %dh
62
63               #i
64 006e 053412CD          addl    \$0xabcd1234, %eax
64      AB
65 0073 81C3ABCD          addl    \$0x3412cdab, %ebx
65      1234
66 0079 81C1D4C3          addl    \$0xa1b2c3d4, %ecx
66      B2A1
67 007f 81C2A1B2          addl    \$0xd4c3b2a1, %edx
67      C3D4
68
69               #o
70 0085 05AB0000          addl    \$0xab, %eax
70      00
71 008a 83C301            addl    \$0x1, %ebx
72 008d 83C100            addl    \$0x0, %ecx
73 0090 81C2FF00          addl    \$0xff, %edx
73      0000
74
75               #k
76 0096 6605CDAB          addw    \$0xabcd, %ax
77 009a 6681C3BA          addw    \$0xcdba, %bx
77      CD
78 009f 6681C134          addw    \$0x1234, %cx
78      12
79 00a4 6681C221          addw    \$0x4321, %dx
79      43
80
81               #l
82 00a9 6605AB00          addw    \$0xab, %ax
84 00b1 6683C100          addw    \$0x0, %cx
85 00b5 6681C2FF          addw    \$0xff, %dx
85      00
86
87               #m
88 00ba 00C4              addb    %al, %ah
89 00bc 4100C2            addb    %al, %r10b
90 00bf 00CA              addb    %cl, %dl
91 00c1 4500C1            addb    %r8b, %r9b
92
93               #n
94 00c4 01C3              addl    %eax, %ebx
95 00c6 6601D8            addw    %bx, %ax
96 00c9 4801CA            addq    %rcx, %rdx
97 00cc 4501C6            addl    %r8d, %r14d
98
99 00cf B8000000