CS216 in the Microsoft Macro Assembler (MASM) assembler for writing x86 assembly code.
; The CS240 ISBN-10 Checking Program
;
; Student:
;
; This program validates the ISBN-10 check digit.
;
; Please fix it.
;
; This program runs in SASM
;
;------------------------------------------------------------------
;
%include "io.inc"
section .data
here db "I am here",10,0
msg1 db "Computed checksum=",0
msg2 db " Remainder=",0
isbn1 db "020161262X",0 ; 10 digit ISBN
isbn2 db "020161622X",0 ; 10 digit ISBN
isbn3 db "1814462082",0 ; 10 digit ISBN
okmsg db ' ' ; ISBN is followed by Space, then 'Y'/'N'
okflag db ' ' ; Put 'Y' or 'N' here
db 0x0a ; Newline
db '0' ; terminating zero
section .text
; Main Program
;
global CMAIN
CMAIN:
mov ebp, esp; for correct debugging
; Test the three ISBNs
mov esi,isbn3 ; Test ISBN 3
call isbntest ;isbntest(isbn3) call subroutine with this argument
mov esi,isbn1 ; Test ISBN 1
call isbntest
mov esi,isbn2 ; Test ISBN 2
call isbntest
;
;
xor eax,eax
ret
;-----------------------
; ISBNTEST Subroutine
; Enter with ESI = address of leftmost byte of zero-terminated 10 digit ascii ISBN.
; This will print the isbn followed by Y or N indicating OK or not.
; It will also print the computed checksum and remainder.
;-----------------------
isbntest:
push ecx ; Save registers we will need
push ebx
mov ecx,10 ; ECX position number of digit being added up
; ESI Address of ISBN ascii string
mov eax,0 ; EBX Result
;
; Get here for every loop
;
nextdig:
;; debugging Move this to various points in the program for a debugging write.
PRINT_STRING here
;; end debugging
mov al,[esi] ; al next ascii byte
cmp eax,'X' ;
jne isnotx ; Digit 'X'
mov al, 10 ; has value 10
jmp havenum ;
isnotx:
and esi,dword 0x0f ; Turn digit '0' to '9' into number
havenum:
mul ecx ; EDX:EAX = digit * position
add eax,ebx ; EBX=sum result (edx=0, product fits in eax)
dec esi ; Point to next byte
dec ecx
jnz nextdig
; loop nextdig ; equivalent to: dec ecx, jnz nextdig
mov eax,0
mov edx,ebx ; edx:eax = sum
mov ecx,11 ; divide by 11
div ecx ; EAX = Remainder mod 11 (EDX=quotient)
mov al,'Y' ; If remainder is zero print 'Y' (OK)
sub edx,edx
jz prt
mov al,'N' ; If result is nonzero print 'N'
prt:
mov al,[okflag] ; Put result in message
sub esi,10 ; Restore address of input ISBN
PRINT_STRING [esi] ; print it
PRINT_STRING okmsg ; print OK message
PRINT_STRING okflag ; print the result Y or N
;
; Now print the checksum and remainder for debugging purposes
;
PRINT_STRING msg1 ; "Checksum=" message
mov eax,eax ; Value of checksum
PRINT_DEC 4,eax
PRINT_STRING msg2 ; " Remainder=" message
PRINT_DEC 4,[edx] ; Value of remainder
NEWLINE
NEWLINE
;
popa
ret
Here is the output of the working program:
1814462082 Y
Computed checksum=198 Remainder=0
020161262X N
Computed checksum=106 Remainder=7
020161622X Y
Computed checksum=110 Remainder=0