## Project 1: ISBN Validation

### Objective

Through this project, you will practice writing loops and using conditional jumps in assembly language.

### Background

The 10-digit ISBN number is a simple example of an error-detecting code. (ISBN stands for "International Standard Book Number" and is used as a unique identifier for books.) Not all 10-digit numbers are valid ISBN numbers. If a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 is a valid ISBN number, then the digits must satisfy the condition that 10*a0 + 9*a1 + 8*a2 + 7*a3 + 6*a4 + 5*a5 + 4*a6 + 3*a7 + 2*a8 + a9 is divisible by 11. For example, 3201541974 is a valid ISBN number because 10*3 + 9*2 + 8*0 + 7*1 + 6*5 + 5*4 + 4*1 + 3*9 + 2*7 + 4 = 154 and 154 = 11 * 14. On the other hand, 0457773706 is not a valid ISBN number because 10*0 + 9*4 + 8*5 + 7*7 + 6*7 + 5*7 + 4*3 + 3*7 + 2*0 + 6 = 241 and 241 is not divisible by 11. In fact, if you take a valid ISBN number and change just one digit or swap two adjacent digits, then the resulting number cannot be a valid ISBN number. (This is easily verified by arithmetic. All you need is that 11 is prime and is also bigger than 10.) Thus, this error-detecting code will catch some simple typographical errors.

When a publisher picks an ISBN number, the first 9 digits are selected. Then the 10th digit is used to push the sum to the next multiple of 11. This 10th digit is called the check digit. For example, if we took the first 9 digits of the invalid number above: 045777370, we have

10*0 + 9*4 + 8*5 + 7*7 + 6*7 + 5*7 + 4*3 + 3*7 + 2*0 = 235 We should select the check digit to be 7 because 235 + 7 = 242, which is divisible by 11. Another way to think of this is that 235 % 11 = 4 and 4 + 7 = 11. Thus, 0457773707 is a valid ISBN.

Now, it is possible that the sum from the first 9 digits has a remainder of 1 modulo 11. In that case, we need to add 10 to make the sum divisible by 11. For these numbers, the ISBN ends with X. For example, consider the 9 digits 044101125:

10*0 + 9*4 + 8*4 + 7*1 + 6*0 + 5*1+ 4*1 + 3*2 + 2*5 = 100 Since 110 is the next multiple of 11, we need to add X to make 044101125X a valid ISBN number. (This happens to be the 6th book in Ursula LeGuin's outstanding Earthsea Trilogy.)

### Assignment

Your assignment for this project is to write an assembly language program that checks if the user's input is a valid ISBN number. A sample run of your program might look like: linux3% ./a.out Enter 10 digit ISBN: 3201541974 This is a valid ISBN number. linux3% linux3% ./a.out Enter 10 digit ISBN: 0457773706 This is NOT a valid ISBN number. linux3% linux3% ./a.out Enter 10 digit ISBN: 044101125X This is a valid ISBN number. linux3% Two simple tricks remove the need to use the multiplication or division instructions in assembly. Let's start with the naive code to compute the sum assuming that the digits are stored in an array a ... a: sum = 0 ; for ( i = 0 ; i < 10 ; i++ ) { sum += (10 - i) * a[i] ; } Instead, we can keep a sum of the digits seen so far in a variable t: sum2 = 0 ; t = 0 ; for ( i = 0 ; i < 10 ; i++ ) { t += a[i] ; sum2 += t ; } Note that in this scheme a is added to sum2 10 times, once for each iteration of the loop. Also, a is added to sum2 9 times, ...

For example, for the number 3201541974, at bottom of the for loop, the values of the variables are:

i a[i] (10-i)*a[i] sum t sum2
0 3 30 30 3 3
1 2 18 48 5 8
2 0 0 48 5 13
3 1 7 55 6 19
4 5 30 85 11 30
5 4 20 105 15 45
6 1 4 109 16 61
7 9 27 136 25 86
8 7 14 150 32 118
9 4 4 154 36 154

This example illustrates that sum and sum2 arrive at the same value. Furthermore, we do not need to compute t and sum2 since we only need to decide whether the result is divisible by 11. Thus, we can do all of our arithmetic modulo 11:

sum3 = 0 ; t3 = 0 ; for ( i = 0 ; i < 10 ; i++ ) { t3 = (t3 + a[i]) % 11 ; sum3 = (sum3 + t3) % 11 ; } Using the example 3201541974 again, we have:

i a[i] t sum2 t3 sum3
0 3 3 3 3 3
1 2 5 8 5 8
2 0 5 13 5 2
3 1 6 19 6 8
4 5 11 30 0 8
5 4 15 45 4 1
6 1 16 61 5 6
7 9 25 86 3 9
8 7 32 118 10 8
9 4 36 154 3 0

Finally, in modulo 11 arithmetic, all the numbers involved are less than 11, so we can replace the % operator with an if statement:

sum4 = 0 ; t4 = 0 ; for ( i = 0 ; i < 10 ; i++ ) { t4 += a[i] ; if (t4 >= 11) t4 -= 11 ; sum4 += t4 ; if (sum4 >= 11) sum4 -= 11 ; }

It is this last version that you should implement in assembly language.

### Implementation Notes

1. A good starting point for your program is the toupper.asm program shown in class. It already queries the user for input and sets up a loop that looks at each character of the input. The source code for toupper.asm is available on the GL file system in: /afs/umbc.edu/users/c/h/chang/pub/cs313/

2. The bytes entered by the user are ASCII characters. You should convert this to a numerical digit by subtracting the character '0'.

3. Recall that the last character might be an X and represents the value 10. You will need to special case this. For simplicity, let's not worry about an X appearing in the middle of the input.

4. You should set up your loop to iterate 10 times and NOT for the length of the string (as is done in toupper.asm) because that will include the newline character at the end of the user input.

5. Do NOT use the multiplication and division instructions. (Yes, the graders will take off points.)

6. Since all the numbers are small, you can use the 8-bit portions of the general purpose registers: AH, AL, BH, BL, CH, CL, DH and DL. This is convenient because you have more registers to play with and because you won't have to mix 8-bit and 32-bit arithmetic.

7. Develop your program incrementally. After each step, use the debugger to check that you have accomplished the desired goal.
1. Set up the loop to iterate 10 times, each time storing the next character in an 8-bit register (say AL).
2. Convert AL into a "number".
3. Add the special case where AL might be X.
4. Compute t in another 8-bit register.
5. Compute t % 11.
6. Compute sum % 11 in another 8-bit register.
7. Print out the correct message to the user.

### Extra Credit

For 10 points extra credit, submit a separate assembly language program that prints out the value of the check digit given the first 9 digits of an ISBN number. A sample run of your program might look like: linux2% ./a.out Enter first 9 digits of ISBN #: 320154197 Check digit: 4 linux2% linux2% ./a.out Enter first 9 digits of ISBN #: 045777370 Check digit: 7 linux2% linux2% ./a.out Enter first 9 digits of ISBN #: 044101125 Check digit: X linux2%

The extra credit policy for this class is that extra credit is only given for programs that are mostly correct. A half-hearted attempt at extra credit that doesn't really work will receive 0 extra credit points. (This is to have you concentrate on the regular portion of the assignment.)

If your extra credit program is working, submit an additional file called ec1.asm to proj1. You still need to submit the regular program and typescript file.

### What to submit

Using the UNIX script command, record some sample runs of your program and a debugging session using gdb. In this session, you should fully exercise the debugger. You must set several breakpoints, single step through some instructions, use the automatic display function and examine the contents of memory before and after processing. The script command is initiated by the command script. This puts you in a new UNIX shell which records every character typed or printed to the screen. You exit from this shell by typing exit at the UNIX prompt. A file named typescript is placed in the current directory.

Use the UNIX submit command on the GL system to turn in your project. You should submit two files: 1) the assembly language program and 2) the typescript file of your debugging session. The class name for submit is cs313 and the project name is proj1. The UNIX command to do this should look something like:

submit cs313 proj1 isbn.asm typescript to Spring 2013 CMSC 313 Homepage