; (c) xrnd [2010] [http://asmworld.ru/]
; printhex.asm - вывод чисел в шестнадцатеричном виде

use16			    ;Генерировать 16-битный код
org 100h		    ;Программа начинается с адреса 100h

    mov ax,0xA15F	    ;Число, которое будем выводить
    mov cx,print_str	    ;Адрес процедуры print_str
    mov bx,print_endline    ;Адрес процедуры print_endline

    mov di,s_byte
    call cx		    ;Вывод строки 'byte:'
    call print_byte_hex     ;Вывод AL в шестнадцатеричном виде
    call bx		    ;Вывод конца строки
    mov di,s_word
    call cx		    ;Вывод строки 'word:'
    call print_word_hex     ;Вывод AX в шестнадцатеричном виде
    call bx		    ;Вывод конца строки

    mov di,s_pak
    call cx		    ;Вывод строки 'Press any key...'
    mov ah,8		    ;Функция DOS 08h - ввод символа без эха
    int 21h

    mov ax,4C00h	    ;\
    int 21h		    ;/ Завершение программы

;----------------------------------------------------------------------
;Процедура вывода байта на консоль в шестнадцатеричном виде
; AL - байт
print_byte_hex:
    push di
    mov di,buffer	    ;DI = адрес буфера
    call byte_to_hex_str    ;Преобразование байта в AL в строку
    mov byte[di],'$'	    ;Добавление символа конца строки
    sub di,2		    ;DI = адрес начала строки
    call print_str	    ;Вывод строки на консоль
    pop di
    ret

;----------------------------------------------------------------------
;Процедура вывода слова на консоль в шестнадцатеричном виде
; AX - слово
print_word_hex:
    push di
    mov di,buffer	    ;DI = адрес буфера
    call word_to_hex_str    ;Преобразование слова в AX в строку
    mov byte[di],'$'	    ;Добавление символа конца строки
    sub di,4		    ;DI = адрес начала строки
    call print_str	    ;Вывод строки на консоль
    pop di
    ret

;----------------------------------------------------------------------
;Процедура вывода строки на консоль
; DI - адрес строки
print_str:
    push ax
    mov ah,9		    ;Функция DOS 09h - вывод строки
    xchg dx,di		    ;Обмен значениями DX и DI
    int 21h		    ;Обращение к функции DOS
    xchg dx,di		    ;Обмен значениями DX и DI
    pop ax
    ret

;----------------------------------------------------------------------
;Процедура вывода конца строки (CR+LF)
print_endline:
    push di
    mov di,endline	    ;DI = адрес строки с символами CR,LF
    call print_str	    ;Вывод строки на консоль
    pop di
    ret

;----------------------------------------------------------------------
;Процедура преобразования числа (0-15) в шестнадцатеричную цифру
; вход : AL - число (0-15)
; выход: AL - шестнадцатеричная цифра ('0'-'F')
to_hex_digit:
    add al,'0'		    ;Прибавляем символ '0' (код 0x30)
    cmp al,'9'		    ;Сравнение с символом '9' (код 0x39)
    jle thd_end 	    ;Если получилось '0'-'9', то выход
    add al,7		    ;Прибавляем ещё 7 для символов 'A'-'F'
thd_end:
    ret

;----------------------------------------------------------------------
;Процедура преобразования байта в строку в шестнадцатеричном виде
; AL - байт.
; DI - буфер для строки (2 символа). Значение регистра не сохраняется.
byte_to_hex_str:
    push ax
    mov ah,al		    ;Сохранение значения AL в AH
    shr al,4		    ;Выделение старшей тетрады
    call to_hex_digit	    ;Преобразование в шестнадцатеричную цифру
    mov [di],al 	    ;Добавление символа в строку
    inc di		    ;Инкремент DI
    mov al,ah		    ;Восстановление AL
    and al,0Fh		    ;Выделение младшей тетрады
    call to_hex_digit	    ;Преобразование в шестнадцатеричную цифру
    mov [di],al 	    ;Добавление символа в строку
    inc di		    ;Инкремент DI
    pop ax
    ret

;----------------------------------------------------------------------
;Процедура преобразования слова в строку в шестнадцатеричном виде
; AX - слово
; DI - буфер для строки (4 символа). Значение регистра не сохраняется.
word_to_hex_str:
    xchg ah,al		    ;Обмен AH и AL
    call byte_to_hex_str    ;Преобразование старшего байта в строку
    xchg ah,al		    ;Обмен AH и AL
    call byte_to_hex_str    ;Преобразование младшего байта в строку
    ret

;---------------------------------------------------------------------
; Данные
s_byte	db 'byte: $'
s_word	db 'word: $'
s_pak	db 'Press any key...$'
endline db 13,10,'$'
buffer	rb 5
