NASM memory operands use square brackets to denote dereferencing. So for example you will want:
mov al, [HNUM]
div byte [D]
mov [HNUM], al
The NASM Manual explains this. RTFM!
Without the brackets, the labels are treated as immediate operands equal to the address of the memory location. The first line is no syntax error, but causes al
to be loaded with the low byte of the address of HNUM
. Not what you wanted. The div
is an error because 8086 has no instruction to divide by an immediate quantity. And the mov
is nonsense because you can't write to an immediate value.
So the error messages are telling you what's wrong. In the lines referenced, the operands do not comport with their instructions.
Addition
I went ahead and installed dosbox and NASM. Indeed NASM is not quite as smart as MASM about inferring operand types. So for the div
instruction you need byte
, (not word
) as now reflected above. I could not grok your algorithm. It's more complicated than necessary. Here is my version:
; This program gets a hex digit from user and prints it out as a decimal
org 100h ; program start point
section .data
msgIn: DB 13, 10, "Enter a hex digit or q to quit: $"
msgErr: DB " isn't hex. Must be 0-9, A-F, or a-f.$"
msgOut: DB " has decimal value $"
buffer: DB "xxxxx"
endBuf: DB ".$"
ten: DB 10
section .text
continue: ; start user interaction
mov dx, msgIn ; offset address of message to display
mov ah, 9 ; print string function
int 21h
get_hex_digit:
mov ah, 1
int 21h ; read character into al
check_for_quit:
cmp al, 'q' ; handle quit character
je exit
cmp al, 'Q'
je exit
check_for_digit:
cmp al, '0' ; handle 0-9
jl check_for_upper
cmp al, '9'
jg check_for_upper
sub al, '0' ; convert to numeric value
jmp print_decimal
check_for_upper:
cmp al, 'A' ; handle A-F
jl check_for_lower
cmp al, 'F'
jg check_for_lower
sub al, 'A'-10 ; convert to numeric value
jmp print_decimal
check_for_lower:
cmp al, 'a' ; handle a-f
jl handle_digit_error
cmp al, 'f'
jg handle_digit_error
sub al, 'a'-10 ; convert to numeric value
print_decimal: ; print al contents as decimal 0-255
mov di, endBuf ; set buffer pointer to char after digits
next_digit:
dec di ; advance buffer pointer to next char
xor ah, ah ; clear high byte of ax for division
div byte [ten] ; ah = ax % 10, al = ax / 10
add ah, '0' ; convert ah to ascii
mov [di], ah ; copy to buffer
or al, al ; set condition codes with al
jnz next_digit ; jump if more digits to print
print_digits:
mov dx, msgOut ; offset address of message preamble
mov ah, 9 ; print string function
int 21h
mov dx, di ; offset address of converted digits
mov ah, 9 ; print string function
int 21h
jmp continue ; otherwise, get next input
handle_digit_error:
mov dx, msgErr ; offset address of message to display
mov ah, 9 ; print string function
int 21h
jmp continue
exit: ; exit program
mov ah, 4ch ; exit to DOS function
int 21h ; see you later!