You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

#### 113 lines 3.7 KiB NASM Raw Blame History

 ```; From Ed Beroset - ISBN validation ``` ```; > Anyone know how to validate the ISBN numbers from books? ``` ``` ``` ```; isbnchek.asm ``` ```comment ^ ``` ``` ``` ``` This file contains a C-callable routine which calculates the ``` ``` check digit (tenth digit) of an ISBN and returns the ASCII ``` ``` representation of that digit. ``` ``` ``` ``` This code was written for Borland's TASM ``` ``` and may be assembled with the following command: ``` ``` ``` ``` tasm /m2 isbnchek.asm ``` ``` ``` ```^ ``` ``` .MODEL small ``` ``` ``` ``` public isbncheck ``` ``` ``` ``` .CODE ``` ```;/*************************************************************************** ``` ```; ``` ```; Name: ``` ```; isbncheck ``` ```; ``` ```; Purpose: ``` ```; Calculates the check digit for a ten digit ISBN, converts that ``` ```; digit to its ASCII representation and returns that answer. ``` ```; ``` ```; Algorithm: ``` ```; An ISBN consists of nine digits plus a validation digit. ``` ```; Number the digits from left to right as d1, d2, ... d9, with ``` ```; d10 being the validation digit. The calculation is then ``` ```; ``` ```; d10 = (1(d1) + 2(d2) + 3(d3) + ... + i(di) + ... + 9(d9))%11 ``` ```; ``` ```; or the weighted sum of each digit mod eleven. ``` ```; ``` ```; In our assembly language implementation, we simulate the ``` ```; multiplications by looping through and summing as in the ``` ```; following psuedocode: ``` ```; ``` ```; sum = 0 ``` ```; for i=1 to 9 ``` ```; { ``` ```; for j=i to 9 ``` ```; { ``` ```; sum = sum + isbn[j] ``` ```; } ``` ```; } ``` ```; ``` ```; Entry: ``` ```; ``` ```; isbn = a nine digit ASCII string containing the ISBN ``` ```; (with or without the check digit which is not used here) ``` ```; ``` ```; Register usage within the routine: ``` ```; ``` ```; AL = current ISBN digit ``` ```; AH = sum of digits so far ``` ```; BX = start pointer into ISBN for each outer loop ``` ```; CX = digit counter (inner loop) ``` ```; DX = start value for digit counter ``` ```; SI = points to current ISBN digit ``` ```; ``` ```; Exit: ``` ```; ``` ```; AX = ASCII representation of calculated check digit ``` ```; ``` ```; Trashed: ``` ```; none ``` ```; ``` ```;***************************************************************************/ ``` ```isbncheck proc C isbn:ptr byte ``` ``` push bx ``` ``` push cx ``` ``` push dx ``` ``` push si ``` ``` mov bx,[isbn] ; ``` ``` mov dx,9 ; number of digits in raw ISBN ``` ``` xor ax,ax ; clear out our total ``` ``` cld ; count up ``` ```@@bigloop: ; ``` ``` mov si,bx ; point to a digit in the ISBN ``` ``` mov cx,dx ; get digit count in CX ``` ```@@AddEmUp: ; ``` ``` lodsb ; fetch digit into AL ``` ``` and al,0fh ; convert from ASCII ``` ``` add ah,al ; add it to our total in AH ``` ``` loop @@AddEmUp ; do all digits ``` ``` inc bx ; and advance the digit pointer ``` ``` dec dx ; now decrement digit count ``` ``` jnz @@bigloop ; keep going if digits left ``` ``` mov al,ah ; move sum into al ``` ``` xor ah,ah ; clear out high half ``` ``` mov cl,11 ; we'll be doing a mod 11 operation ``` ``` div cl ; ah = sum mod 11 ``` ``` mov al,ah ; move calculated check digit to AL ``` ``` xor ah,ah ; clear out high half ``` ``` or al,30h ; convert to ASCII digit ``` ``` cmp al,3Ah ; ``` ``` jnz NotTen ; ``` ``` mov al,'X' ; ``` ```NotTen: ; ``` ``` pop si ``` ``` pop dx ``` ``` pop cx ``` ``` pop bx ``` ``` ret ; return ``` ```isbncheck endp ``` ``` ``` ` END`