3

pretty new to 8086 Assembly and I'm having an error I can't seem to figure out..

The div process (maybe other stuff before as well) is giving me errors when the 4th digit (for example 123X) is 0 or 1, error is Divide by zero, it also doesn't always work with other numbers..

What I need to do is take input of 4 digit number, make sure input is correct, take sum of 4 digits and divide the number with the sum of the 4 digits, if there is no remainder it's Harshad number, after that need to check special case, if the flipped sum of 4 digits works as well.

For example the number 1729, the sum is 19 and flipped is 91, both can be divided with 1729 with no remainder. Here is my code... sorry if it's too long...

; Harshad.asm - check if input from user (4 digits, 1000-9999) is a Harshad number and if so, check if it's a "special" Harshad number
;
    .MODEL SMALL
    .STACK 100h
    .DATA
RequestStr     DB 'Enter a 4 digit number (1000-9999):',13,10,'$'
IsHarshad      DB ' is a Harshad number.$',13,10
SpecialHarshad DB 13,10,'It is also a special Harshad number.',13,10,'$'
NotHarshad     DB ' is not a Harshad number$',13,10
IncorrectInput DB 13,10,'Input is incorrect.',13,10,'$'
Num            DW ? ;Will fit a "word" size (16 bits)
DigitSum       DB ? ;Sum of digits (maximum 9*4) fits a "byte" size (8 bits)
TEN            DB 10
Temp           DB ? ;Used to check if number is also special Harshad
;
     .CODE
     MOV AX,@DATA                ;DS can be written to only through a register
     MOV DS,AX                   ;Set DS to point to data segment
     MOV AH,9                    ;Set print option for INT 21h
     MOV DX,OFFSET RequestStr    ;Set  DS:DX to point to RequestString
     INT 21h                     ;Print RequestStr
    ;
NumberInput:
    ;First digit
    MOV AH,1        ;Set scanning (input) option for INT 21h
    INT 21h         ;Scan first digit
    SUB AL,'0'      ;Converting from ascii value to numeral value
    CMP AL,1        ;First digit must be between 1 and 9 in order for the number to be of 4 digits
    JB WrongInput   ;Otherwise jump to WrongInput label
    CMP AL,9
    JA WrongInput
    MOV DigitSum,AL ;Store only first digit's value at the variable DigitSum
    MOV AH,0        ;Set AH to zero so it won't affect the answer
    MUL TEN         ;multiply AX by 10
    MOV Num,AX
    ;Second digit
    MOV AX,0
    MOV AH,1 
    INT 21h
    SUB AL,'0'
    CMP AL,0
    JB WrongInput
    CMP AL,9
    JA WrongInput
    MOV AH,0
    ADD DigitSum,AL ;Add only second's digit value to DigitSum
    ADD Num,AX      ;Add AX's value (which has been multiplied by 10 with the first digit) to Num variable
    MOV AX,0
    MOV AX ,Num     ;Move new Num's value to AX to multiply it by 10
    MUL TEN
    MOV Num,AX
    ;Third digit
    MOV AX,0
    MOV AH,1
    INT 21h
    SUB AL,'0'
    CMP AL,0
    JB WrongInput
    CMP AL,9
    JA WrongInput
    ADD DigitSum,AL
    MOV AH,0
    ADD Num,AX
    MOV AX,0
    MOV AX,Num
    MUL TEN
    MOV Num,AX
    ;Forth digit
    MOV AX,0
    MOV AH,1 
    INT 21h
    SUB AL,'0'
    CMP AL,0
    JB WrongInput
    CMP AL,9
    JA WrongInput
    ADD DigitSum,AL ;Now DigitSum contains the sum of each of the 4 digits in the number
    MOV AH,0
    ADD Num,AX ;Num contains full 4 digits number
    JMP CheckHarshad    
WrongInput:      
    MOV AH,9
    MOV DX,OFFSET IncorrectInput
    INT 21h
    JMP CodeEnd
CheckHarshad:
    MOV AX,0
    MOV AX,Num
    DIV DigitSum ;Number will be stored in AL and the remainder in AH
    CMP AH,0 ;Check if there is remainder or not
    JE CheckSpecialHarshad
    MOV AH,9
    MOV DX,OFFSET NotHarshad 
    INT 21h
    JMP CodeEnd
CheckSpecialHarshad:
    MOV AH,9
    MOV DX, OFFSET IsHarshad
    INT 21h
    MOV AX,0
    MOV AL,DigitSum
    DIV TEN
    MOV Temp,AL
    MOV DigitSum,AH
    MOV AX,0
    MOV AL,DigitSum
    MUL TEN
    ADD AL,Temp
    MOV DigitSum,AL ;DigitSum now has it's former number flipped
    MOV AX,0
    MOV AX,Num
    DIV DigitSum
    CMP AH,0
    JNE CodeEnd
    MOV DX,OFFSET SpecialHarshad
    MOV AH,9
    INT 21h
CodeEnd:
    MOV AH,4Ch
    INT 21h
    END
9
  • 1
    What is your question? Commented Nov 30, 2018 at 14:40
  • For example if I enter the number 1111, the program just gets stuck, in the debugger window it gives an error of "Divide by zero" (which is not correct because it's divided by 4). Commented Nov 30, 2018 at 14:46
  • 1
    My question is what's the issue, how to fix it..? Thanks. Commented Nov 30, 2018 at 14:55
  • 2
    That error is also triggered by overflow. You used a division which produces a 8 bit result and 1111/4=277>255. Use a wider division. Commented Nov 30, 2018 at 14:55
  • @S.Arkab That makes sense. Jester outlined what the problem is. Perhaps he is also going to write an answer. Commented Nov 30, 2018 at 14:57

1 Answer 1

3

With @Jester 's help, I changed some of the values, and here's the end result (an Assembly code which checks if the 4 digits number is Harshad number and if so, also check if it's special Harshad number):

; Harshad.asm - check if input from user (4 digits, 1000-9999) is a Harshad number and if so, check if it's a "special" Harshad number
;
    .MODEL SMALL
    .STACK 100h
    .DATA
RequestStr     DB 'Enter a 4 digit number (1000-9999):',13,10,'$'
IsHarshad      DB ' is a Harshad number.',13,10,'$'
SpecialHarshad DB 'It is also a special Harshad number.',13,10,'$'
NotHarshad     DB ' is not a Harshad number',13,10,'$'
IncorrectInput DB 13,10,'Input is incorrect.',13,10,'$'
Num            DW ? ;Will fit a "word" size (16 bits)
DigitSum       DW ? ;Sum of digits
TEN            DW 10
TENbyte        DB 10
Temp           DB ? ;Used to check if number is also special Harshad during the div process
Temp2          DB ? ;Used with special Harshad div process  
;
     .CODE
     MOV AX,@DATA                ;DS can be written to only through a register
     MOV DS,AX                   ;Set DS to point to data segment
     MOV AH,9                    ;Set print option for INT 21h
     MOV DX,OFFSET RequestStr    ;Set DS:DX to point to RequestString
     INT 21h                     ;Print RequestStr
;
NumberInput:
    ;First digit
    MOV AH,1        ;Set scanning (input) option for INT 21h
    INT 21h         ;Scan first digit
    MOV DX,0
    SUB AL,'0'      ;Converting from ascii value to numeral value
    CMP AL,1        ;First digit must be between 1 and 9 in order for the number to be of 4 digits
    JB WrongInput   ;Otherwise jump to WrongInput label
    CMP AL,9
    JA WrongInput
    MOV AH,0
    MOV DigitSum,AX ;Store only first digit's value at the variable DigitSum
    MUL TEN         ;Multiply AX by 10
    MOV Num,AX
    ;Second digit
    MOV AX,0
    MOV AH,1 
    INT 21h
    SUB AL,'0'
    CMP AL,0
    JB WrongInput
    CMP AL,9
    JA WrongInput
    MOV AH,0
    ADD DigitSum,AX ;Add only second's digit value to DigitSum
    ADD Num,AX      ;Add AX's value (which has been multiplied by 10 with the first digit) to Num variable
    MOV AX,0
    MOV AX,Num      ;Move new Num's value to AX to multiply it by 10
    MUL TEN
    MOV Num,AX
    ;Third digit
    MOV AX,0
    MOV AH,1
    INT 21h
    SUB AL,'0'
    CMP AL,0
    JB WrongInput
    CMP AL,9
    JA WrongInput
    MOV AH,0
    ADD DigitSum,AX
    ADD Num,AX
    MOV AX,0
    MOV AX,Num
    MUL TEN
    MOV Num,AX
    ;Forth digit
    MOV AX,0
    MOV AH,1 
    INT 21h
    SUB AL,'0'
    CMP AL,0
    JB WrongInput
    CMP AL,9
    JA WrongInput
    MOV AH,0
    ADD DigitSum,AX ;Now DigitSum contains the sum of each of the 4 digits in the number
    ADD Num,AX ;Num contains full 4 digits number
    JMP CheckHarshad    
WrongInput:      
    MOV AH,9
    MOV DX,OFFSET IncorrectInput
    INT 21h
    JMP CodeEnd
CheckHarshad:
    MOV AX,0
    MOV DX,0
    MOV AX,Num
    DIV DigitSum ;Number will be stored in AX and the remainder in DX
    CMP DX,0 ;Check if there is remainder or not
    JE CheckSpecialHarshad
    MOV AH,9
    MOV DX,OFFSET NotHarshad 
    INT 21h
    JMP CodeEnd
CheckSpecialHarshad:
    MOV AH,9
    MOV DX, OFFSET IsHarshad
    INT 21h
    MOV AX,0
    MOV AX,DigitSum
    DIV TENbyte
    MOV Temp,AL
    MOV Temp2,AH
    MOV AX,0
    MOV AL,Temp2
    MUL TENbyte
    ADD AL,Temp
    MOV Temp2,AL ;Temp2 now has the DigitSum number flipped
    MOV AX,0
    MOV AX,Num
    DIV Temp2
    CMP AH,0
    JNE CodeEnd
    MOV DX,OFFSET SpecialHarshad
    MOV AH,9
    INT 21h
CodeEnd:
    MOV AH,4Ch
    INT 21h
    END
Sign up to request clarification or add additional context in comments.

5 Comments

Nice to see that you got it working. (+1) I would like to suggest however a shorter code to flip the digitsum: mov al, DigitSum aam xchg al, ah aad mov Temp2, al.
It's such a nice program that I would love to see it appear on the Code Review forum (also Stack Exchange). There's more that can be suggested to turn this program into a little marvel...
@SepRoland Thank you :) Feel free to post it (I don't know much forums except Stack Exchange). Also, did the code as above since I still can't use 'aam/xchg etc.', again feel free to change it if you want, it would be cool to see how it would turn out.
I can't really post it myself (asker) because ultimately I would like to be the reviewer (answerer). In general, and over-simplifying, Stack Overflow is where you get the corrections and Code Review is where you get the improvements.
Good to know! Will make an account and post it there tomorrow.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.