; (c) xrnd [2010] [http://asmworld.ru/]
; printoct.asm - вывод чисел в восьмеричном виде

use16			    ;Генерировать 16-битный код
org 100h		    ;Программа начинается с адреса 100h

    mov ax,0x89AB	    ;Число, которое будем выводить
    mov cx,print_str	    ;Адрес процедуры print_str
    mov bx,print_endline    ;Адрес процедуры print_endline

    mov di,s_byte
    call cx		    ;Вывод строки 'byte:'
    call print_byte_oct     ;Вывод AL в восьмеричном виде
    call bx		    ;Вывод конца строки
    mov di,s_word
    call cx		    ;Вывод строки 'word:'
    call print_word_oct     ;Вывод 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_oct:
    push di
    mov di,buffer	    ;DI = адрес буфера
    call byte_to_oct_str    ;Преобразование байта в AL в строку
    mov byte[di],'$'	    ;Добавление символа конца строки
    sub di,3		    ;DI = адрес начала строки
    call print_str	    ;Вывод строки на консоль
    pop di
    ret

;----------------------------------------------------------------------
;Процедура вывода слова на консоль в восьмеричном виде
; AX - слово
print_word_oct:
    push di
    mov di,buffer	    ;DI = адрес буфера
    call word_to_oct_str    ;Преобразование слова в AX в строку
    mov byte[di],'$'	    ;Добавление символа конца строки
    sub di,6		    ;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

;----------------------------------------------------------------------
;Процедура преобразования байта в строку в восьмеричном виде
; AL - байт.
; DI - буфер для строки (3 символа). Значение регистра не сохраняется.
byte_to_oct_str:
    push ax
    push cx
    mov ah,al		    ;Сохранение значения AL в AH
    mov cx,6		    ;Счётчик сдвигов
btos_lp:
    shr al,cl		    ;Сдвиг AL на CL бит вправо
    and al,7		    ;Выделение очередной триады
    add al,'0'		    ;Преобразование в восьмеричную цифру
    mov [di],al 	    ;Добавление символа в строку
    inc di		    ;Инкремент DI
    jcxz btos_lp_end	    ;Если CX = 0, то выход из цикла
    mov al,ah		    ;Восстановление AL
    sub cx,3		    ;Уменьшение счетчика сдвигов на 3
    jmp btos_lp
btos_lp_end:
    pop cx		    ;Восстановление регистров
    pop ax
    ret

;----------------------------------------------------------------------
;Процедура преобразования слова в строку в восьмеричном виде
; AX - слово
; DI - буфер для строки (6 символов). Значение регистра не сохраняется.
word_to_oct_str:
    push ax
    push dx
    push cx
    mov dx,ax		    ;Сохранение значения AX в DX
    mov cx,15		    ;Счётчик сдвигов
wtos_lp:
    shr ax,cl		    ;Сдвиг AX на CL бит вправо
    and ax,7		    ;Выделение очередной триады
    add al,'0'		    ;Преобразование в восьмеричную цифру
    mov [di],al 	    ;Добавление символа в строку
    inc di		    ;Инкремент DI
    jcxz wtos_lp_end	    ;Если CX = 0, то выход из цикла
    mov ax,dx		    ;Восстановление AX
    sub cx,3		    ;Уменьшение счетчика сдвигов на 3
    jmp wtos_lp
wtos_lp_end:
    pop cx		    ;Восстановление регистров
    pop dx
    pop ax
    ret

;---------------------------------------------------------------------
; Данные
s_byte	db 'byte: $'
s_word	db 'word: $'
s_pak	db 'Press any key...$'
endline db 13,10,'$'
buffer	rb 7
