programming-examples/assembly/Checks the validity of an ISBN by verifying the checksum.asm

113 lines
3.7 KiB
NASM
Raw Normal View History

2019-11-15 12:59:38 +01:00
; 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