So, I'm figuring out Assembly by writing a function that prints a hexadecimal number.
How function works: in a loop, it gets the last digit of a number, converts it to a char, and replaces char at HEX_OUT string (HEX_OUT: DB "0x0000", 0, so the function is going to rewrite each char to make the corresponding number), and then repeat it until the number will be mapped to the HEX_OUT string, and then it prints it.
But there's a problem with registers that I don't understand.
The problem is that when I put some value into ax register (say, 6), and then place the value of ax into bx register (mov [bx], ax), at the end of the day I get 0x1 printed on my screen, but if I change the instruction to mov [bx], al, I get 0x1fb6 (assuming that the number to be printed is 0x1fb6, it's correct result).
As far as I know about registers, since I placed 6 in ax, al register should be equal to the value of ax.
Please, look at the comment line with [HERE], this where the problem is.
; HEX_OUT ("0x0000") is stored in bx
; hexadecimal number to be printed (0x1fb6) is stored in dx
print_hex:
pusha
mov cx, 0 ; cx = counter
loop1:
cmp cx, 4 ; if counter < 4
jl print ; jump to print
jmp end ; else jump to end
print:
mov ax, dx ; ax = 0x1fb6
and ax, 0x000f ; ax = 6
cmp ax, 9 ; if ax > 9
jg num_to_abc ; make a letter out of char (because hexadecimal)
jmp next ; jump to next
num_to_abc:
add ax, 39
jmp next
next:
add ax, '0' ; make a char out of num
mov bx, HEX_OUT + 5 ; bx now points to last char of string
sub bx, cx ; bx = bx - counter
mov [bx], al ; [HERE] al is currently 54 (6 + '0'). But why al works properly, but ax doesn't?
ror dx, 4 ; put last digit at the beginning (before: 0x1fb6, after: 0x61fb)
inc cx ; counter++
jmp loop1 ; jump back to loop
end:
mov bx, HEX_OUT ; some code
call print_string
popa
ret
print_string function (I don't think there's any problems with it):
print_string:
pusha
mov ah, 0x0e
loop:
mov al, [bx]
cmp al, 0
je return
jmp put_char
put_char:
int 0x10
inc bx
jmp loop
return:
popa
ret