Назад | Начало урока | Вперед
Содержание

Глава 1 (продолжение 1)

Вверх

Рассмотрим процедуру print_el_bin.

;процедура вывода значения ячейки в двоичной системе ***************************
;входные параметры
;tek_el - значение хранящееся в ячейки
;svalue - адрес выводимого значения

print_el_bin proc
push ax
push dx

call readSR

mov dl,tek_el
mov ah,00000001b

;вывод адреса ячейки в 16-ричной форме
mov dh,svalue
mov tek_el,dh
call filter
call cursor_position
add kolonka,2
call print_position
call print_h_el
;*******************

;вывод значения ячейки в 16-ричной форме
mov dh,dl
mov tek_el,dh
call filter
mov kolonka,10
call print_position
call print_h_el
;***********************************************

startpeb:
mov dh,dl
mov tek_el,dh

;вывод номера бита
push ax

mov ah,bit_number
mov tek_el,ah
mov kolonka,17
call print_position
call print_el

inc ah
mov bit_number,ah
pop ax
;*****************

;вывод значения бита
mov al,dl
and al,ah
cmp al,00h
je noll

mov tek_el,"1"
jmp peb1


noll:
mov tek_el,"0"

peb1:
mov kolonka,21
call print_position

call print_el
call corretka
call cursor_position
;***************************************

shl ah,1

cmp ah,00h
jne startpeb

mov bit_number,30h

call corretka

pop dx
pop ax
ret


print_el_bin endp
;******************************************************************************

Анализ:

В процедуру в качестве параметров передаются две переменные: svalue - начальный адрес читаемой CMOS и RTS памяти и tek_el - значение ячейки по указаному адресу.

Вспомним как они были объявлены:

svalue DB 00h ;начальный адрес читаемой CMOS и RTS памяти
tek_el DB 00h ;значение ячейки по указаному адресу

При внимательном посмотрении данной процедуры print_el_bin видно, что код вывода адреса и значения ячейки в 16-ричном виде, переданные через параметр почти в точности совпадает с выводом этих же величин в ранее рассмотренной процедуре menu_byte. И обеспечивается вызовом все тех же процедур - readSR, filter, print_h_el.

Но в код данной процедуры добавлен вывод значения ячейки в двоичном виде. Выводится в двух вертикальных столбцах соответственно номер бита и его значение.

Итак рассмотрим процедуру.

Сохраняем регистры в стеке.


push ax
push dx

Далее, первое, с чем мы столкнулись - это вызов процедуры readSR:

call readSR

Вот процедура readSR, которой через переменную svalue передается адрес ячейки, и которая прочитает
в переменную tek_el значение, содержащееся по этому адресу. Всего одна ячейка!
Но прочитав одну ячейку, мы можем прочитать и все остальные!

Придется рассмотреть процедуру readSR. Процедуре передается адрес ячейки, через переменную svalue, и процедура возвращает прочтенное значение через переменную tek_el.
Интересно, что эта задача решается через обращение к порту 70h.

;процедура чтения значений CMOS и RTS ****************************************
;входные параметры
;svalue - адрес ячейки чтение значения которой производится
;выходные параметры
;tek_el - прочтенное значение

readSR proc
push ax

mov al,svalue ;номер (адрес) ячейки из которой производится чтение
out 70h,al ;заносим это значние в порт smoc rts
wait
xor ax,ax ;очистка регистра ax
in al,71h ;вводим в регистр al из порта значение ячейки smoc rts
wait
mov tek_el,al ;присваеваем tek_el значение ячейки

pop ax
ret

readSR endp
;*****************************************************************************

В переменной tek_el получили значение ячейки, теперь продолжим рассмотрение процедуры print_el_bin.


mov dl,tek_el
mov ah,00000001b

Итак поместили в dl значение ячейки.
Помещение в ah маски 00000001b мне пока не ясно.

;вывод адреса ячейки
mov dh,svalue
mov tek_el,dh
call filter

Теперь поместили в tek_el адрес. Значит первым делом мы будем выводить на эран адрес.
Напомним tek_el - является единственным входным параметром процедуры filter.

Вызвали процедуру filter - преобразовывает число переданное через параметр (tek_el) в шестнадцатиричную форму. Кроме того эта процедура инициализирует переменные first_val и second_val, которые будут использоваться, для вывода 16-ричного числа в процедуре print_h_el.

Сдвинем курсор на две позиции вправо для удобства восприятия.

call cursor_position
add kolonka,2
call print_position

Далее выведем на экран обе цифры 16-ричного числа адреса ячейки при помощи процедуры print_h_el:

call print_h_el
;*******************

И вывели адрес в 16-ричной форме.
Надо сказать, что процедура print_h_el выводит на экран сначала первую цифру адреса, хранящуюся в переменной firstp_val. А эту переменную только что инициировала процедура filter. Затем эта же процедура выводит вторую цифру адреса, хранящуюся в переменной second_val. Эту переменную так же только что инициировала процедура filter.
Обе переменные и first_value и second_value инициировала процедура filter, которой в параметр было передано выводимое число tek_el.

Адрес ячейки вывели. Далее выведем в этой же 16-ричной форме значение ячейки. Значение выводим так же, как мы и выводили адрес. Только передвинем курсор еще на несколько позиций вправо для удобства восприятия.

;вывод значения ячейки в шестнадцатиричной форме
mov dh,dl
mov tek_el,dh
call filter
mov kolonka,10
call print_position
call print_h_el
;***********************************************

Далее нам предстоит еще вывод значения этой же ячейки в двоичном формате. С указанием номера бита, значения бита. И этот код так же есть далее в процедуре print_el_bin:

startpeb:
mov dh,dl
mov tek_el,dh

Снова поместили в переменную tek_el значение из ячейки. Адрес и значение которой только-что выводили в 16-ричном формате.

Далее выведем на экран номер бита.

;вывод номера бита
push ax

mov ah,bit_number
mov tek_el,ah


Мы только что поместили в tek_el номер бита.

Помним, что bit_number имеет значение 30h при объявлении переменных:

bit_number DB 30h ;номер бита

Смотрим далее код процедуры print_el_bin. Теперь в переменной tek_el у нас номер бита для вывода на экран. При помощи функции print_el выведем значение, хранящееся в переменной tek_el в 17-ю колонку:

mov kolonka,17
call print_position
call print_el


Процедура print_el вывела значение, содержащееся в tek_el - это номер бита. (ниже выведем и его значение).

В ah у нас тоже пока значение bit_number. Инкременируем его:

inc ah
mov bit_number,ah ;инкремент bit_number
pop ax
;*****************

Далее код вывода значения этого бита.
Значение будет выведено при помощи процедуры print_el. Будет выведено значение
каждого из 8 бит.

;вывод значения бита
mov al,dl
and al,ah
cmp al,00h
je noll

mov tek_el,"1"
jmp peb1

noll:
mov tek_el,"0"
peb1:

mov kolonka,21
call print_position

call print_el
call corretka
call cursor_position
;***************************************

shl ah,1

cmp ah,00h
jne startpeb

mov bit_number,30h

call corretka

pop dx
pop ax
ret

---------------------

Далее надо еще рассмотреть процедуру print_el.
Ну эта процедура проста:

;процедура вывода символа с учетом цвета *************************************
;входные параметры
;tek_el - выводимый символ

print_el proc
push ax
push dx

mov al,tek_el ;заносим в al вторую цифру числа
mov ah,09h ;номер процедуры BIOS
mov bl,0Fh ;выбор цвета
mov cx,01h ;количество повторений
int 10h ;вызов процедуры BIOS

pop dx
pop ax
ret

print_el endp
;*****************************************************************************

Резюме:

Процедура print_el_bin наиболее сложна для понимания. Особенно код от метки startpeb
и до конца процедуры. Эта процедура выводит сначала адрес ячейки в 16-ричном виде, занем ее значение в 16-ричном виде, затем это значение представляет в двоичном виде так, что сначала выводит номер бита, затем его значение, и так восемь раз, пока не выведет номера и значения всех 8 бит. Выглядеть это будет примерно так:

Подсказка

Здесь 0Ah - адрес ячейки, A6h - ее содержание в 16-ричном виде, и далее в два столбца - номер бита и содержание бита.


Назад | Начало урока | Вверх | Вперед
Содержание

Hosted by uCoz