CMSC313, Computer Organization & Assembly Language Programming, Spring 2013
Project 1: ISBN Validation
Due: Tuesday February 19, 2013 11:59pm
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[0] ... a[9]:
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[0] is added to sum2 10 times, once
for each iteration of the loop. Also, a[1] 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
- 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/
- The bytes entered by the user are ASCII characters. You should
convert this to a numerical digit by subtracting the character '0'.
- 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.
- 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.
- Do NOT use the multiplication and division instructions.
(Yes, the graders will take off points.)
- 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.
- Develop your program incrementally. After each step, use the debugger
to check that you have accomplished the desired goal.
- Set up the loop to iterate 10 times, each time storing the
next character in an 8-bit register (say AL).
- Convert AL into a "number".
- Add the special case where AL might be X.
- Compute t in another 8-bit register.
- Compute t % 11.
- Compute sum % 11 in another 8-bit register.
- 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
Last Modified:
22 Jul 2024 11:28:12 EDT
by
Richard Chang
to Spring 2013 CMSC 313 Homepage