Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Primery_nebolwih_podprogramm_na_Assembl-.doc
Скачиваний:
2
Добавлен:
14.05.2015
Размер:
161.79 Кб
Скачать

Примеры небольших подпрограмм на Ассемблере

  • Чтение строки с клавиатуры

  • Перевод чисел в двоичную форму (в виде строки)

  • Чтение значения счетчика времени

  • Определение типа процессора

  • Установка видеорежимов VGA

  • Запись напрямую в видеопамять

  • Рисование пиксела в различных режимах VGA

  • Рисование в SVGA

  • Линейные преобразования в системах с фиксированной точкой

  • Функция синуса в 32-битной системе с фиксированной точкой

  • Таблица расположения файлов FAT

  • Выполнение дочерней программы

  • Чтение параметров командной строки

  • TSR: Завершаемся и остаемся в памяти

  • Проверка готовности накопителя

KbdInput$ proc ;POW35

; Входные данные: смещение строки в AX

; Выходные данные: строка ASCIIZ, прочитанная с клавиатуры. Регистры не сохраняются.

mov DI,AX ;смещение строки

mov DX,AX ;смещение буфера

mov CX,255 ;максимальное количество читаемых символов

mov BX,0 ;файловый хэндл клавиатуры

mov AH,3Fh ;читаем из файла (фактически - с клавиатуры)

int 21h

jc Input$_error ;если ошибка

dec AX ;убираем символ RETURN

add DI,AX ;смещение байта, расположенного в конце строки

Input$_error:

mov [DI],BL ;завершаем строку, записывая 0 в конец строки

ret

KbdInput$ endp

Перевод чисел в двоичную форму (в виде строки)

Данная процедура конвертирует 16-битное слово в строку ASCIIZ, т.е. число 7 преобразовывается в строку 0000000000000111. Лидирующие нули включаются в строку. Строка ASCIIZ - это набор символов, завершающихся 0.

NmbrToBi$ proc ;POW36

;Входные данные: AX - смещение строки, BX - число, которое необходимо преобразовать

;Выходные данные: Строка ASCIIZ. Регистры не сохраняются.

mov DI,AX ;смещение строки

mov DX,8000h ;проверочное слово, 1 в позиции 15

mov CX,16 ;обрабатываем 16 бит

NumberTo_B0:

mov AL,48 ;символ '0'

test BX,DX ;бит равен 1?

jz NumberTo_B

inc AL ;символ '1'

NumberTo_B:

stosb ;записываем в строку '1' или '0'

shr DX,1 ;сдвигаем тестовый бит вправо

loop NumberTo_B0

mov [DI],DL ;завершаем строку 0

ret

NmbrToBi$ endp

Чтение значения счетчика времени

В памяти по адресу 40:6C расположено двойное слово, которое увеличивается на единицу приблизительно 18.2 раза в секунду. Системное время можно получить, считывая это слово. Младший байт может быть использован для многих "временных" задач, в т.ч. в качестве исходного значения для генератора псевдослучайных чисел (а в некторых случаях и заменить его).

GetTicks proc ;POW37

; Входные данные: нет

; Выходные данные: Младший байт счетчика времени в AX

; Регистры не сохраняются.

mov BX,ES ;Сохраняем адрес дополнительного сегмента

mov AX,40h ;сегмент данных BIOS

mov ES,AX

mov AX,ES:[6Ch] ;читаем счетчик

mov ES,BX ;восстанавливаем регистр ES

ret

GetTicks endp

Определяем тип процессора

Следующая процедура WhatCPU определяет тип процессора, установленного в системе. Результат возвращается в регистре AX. Процедура может быть откомпилирована и 16-битным компилятором, несмотря на то, что в ней используются 32-битные инструкции для определения различия между 386, 486 и Pentium.

WhatCPU proc ;POW38

;Результат в AX

;0: i88,i86, 1: i186, 2: i286, 3: i386, 4: i486, 5: Pentium

pushf ;сохраняем флаги

mov DX,0F000h

sub AX,AX

push AX ;записываем 0 в верхушку стека

popf ;восстанавливаем регистр флагов из стека

pushf ;записываем флаги в стек

pop AX

popf ;восстанавливаем флаги

and AX,DX ;выделяем четыре старших байта

cmp AX,DX ;они равны 1 ?

jne CPU_ei8088

mov AX,0 ;результат 0 (8088 или 8086)

ret

CPU_ei8088:

push SP

pop BX

cmp BX,SP ;изменяется ли указатель стека перед записыванием в него?

je CPU_ei186

mov AX,1 ;результат 1 (80186)

ret

CPU_ei186:

pushf ;сохраняем флаги

mov AX,DX ;0F000h

push AX

popf

pushf

pop AX

popf ;оригинальные флаги

and AX,DX

jne CPU_ei286

mov AX,2 ;результат 2 (80286)

ret

CPU_ei286:

db 66h

pushf ;pushfd

db 66h

pushf ;pushfd

db 66h

pop AX ;pop EAX

db 66h

or AX,0000h

db 04h,00h ;или EAX,00040000h

db 66h

push AX ;push EAX

db 66h

popf ;popfd

db 66h

pushf ;pushfd

db 66h

pop AX ;pop EAX

db 66h

popf ;popfd

db 66h

test AX,0000h

db 04h,00h ;test EAX,00040000h

jnz CPU_ei386

db 66h

mov AX,3 ;результат AX=00000003h (80386)

db 0h,0h

ret

CPU_ei386:

db 66h

pushf ;pushfd

db 66h

pushf ;pushfd

db 66h

pop AX ;pop EAX

db 66h

mov BX,AX ;mov EBX,EAX

db 66h

xor AX,0000h

db 20h,00h ;xor EAX,00200000h

db 66h

push AX ;push EAX

db 66h

popf ;popfd

db 66h

pushf ;pushfd

db 66h

pop AX ;pop EAX

db 66h

popf ;popfd

db 66h

and AX,0000h

db 20h,00h ;and EAX,00200000h

db 66h

and BX,0000h

db 20h,00h ;and EBX,00200000h

db 66h

cmp AX,BX ;cmp EAX,EBX

jne CPU_ei486

db 66h

mov AX,4 ;результат EAX=00000004h (80486)

db 0h,0h

db 66h ;обнуление 32 битных регистров

xor BX,BX ;xor EBX,EBX

ret

CPU_ei486: ;Pentium

db 66h

mov AX,5 ;результат EAX=00000005h (Pentium)

db 0h,0h

db 66h

xor BX,BX ;xor EBX,EBX

ret

WhatCPU endp

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]