Test whether a number is a Harshad Number
Written for NASM


Your program is a little hard to follow, mostly due to poor formatting. There is a lot of unnecessary duplication too and the user has no opportunity for correcting mistakes. The following prologue will address these initial criteria;


Prompt operator for what is required.
Use a function that allows the user to correct mistakes.
Test that entry is 4 characters long and the first digit is not zero.




      org   0x100

      DOS   equ 21H
     SHOW   equ  9
 BUFFERED   equ 10  ; Buffered input
   OUTCHR   equ  2
   GETCHR   equ  8


Begin:  mov ah, SHOW        ; Function 9 display string terminated with '$'
        mov dx, Prompt
        int DOS

        mov ah, BUFFERED    ; Function 10 Get buffered input
        mov dx, Entry
        int DOS

; Test that your criteria of 4 character entry and first digit not zero has been met.

        cld                 ; Make sure SI auto-increments
        mov si, dx
        inc si              ; Point to number of characters entered
        lodsb
        or  al, al
        jz  Err             ; You might want to put some sort of prompting text here
        cmp al, 4   
        jnz Err
        cmp byte [si], '1'
        jae Evaluate

Err:    mov ah, SHOW        ; Function 9 again
        mov dx, ErrTxt
        int DOS
        ret                 ; Return to DOS


You do have these elements in your program, but I think you'll agree when there are in one place it's a lot easier to recognize which error testing mechanism has been implemented. Notice too, formatting is monumentally important, especially in ASSM.

Now we are ready to do the calculations and because we're not going to be using any DOS functions, there is a little more freedom in which registers we can use and for what. The criteria now becomes, establish a binary value of our entry and binary total of all digits.

Evaluate:

    ; AX = Working register, CX = character count

        movzx   cx, al      ; Move character count into CX
        xor     dx, dx      ; DX will be binary representation of input
        mov     bx, dx      ; BL will be total of digits
        mov     ax, dx

  .get: lodsb           ; Read character from input string
        cmp     al, '0'
        jb      Err
        cmp     al, '9'
        ja      Err

       and      ax, 1111b   ; Could be SUB AL,'0' too.
       add      bl, al      ; Bump total of digits
       xchg     ax, dx
       imul     ax, 10
       add      dx, ax
       loop     .get

     ; Now DX = Binary equivalent and BL divisor

        xor     ax, ax
        xchg    ax, dx
        push    ax          ; Going to need this again to determine if Special
        idiv    bx
        or      dl, dl      ; Determine if value is Harshad or not.


From this point I'd pretty much be doing the same as you have except there is still no need to address anything in memory other than prompting text as everything you need is on the stack and BL. Let us know what you come up with then we'll compare it with what I have.