Основы микропроцессорной техники

Автор работы: Пользователь скрыл имя, 17 Января 2012 в 13:41, курсовая работа

Краткое описание

Операционная система, сокр. ОС (англ. operating system) — комплекс управляющих и обрабатывающих программ, которые, с одной стороны, выступают как интерфейс между устройствами вычислительной системы и прикладными программами, а с другой стороны — предназначены для управления устройствами, управления вычислительными процессами, эффективного распределения вычислительных ресурсов между вычислительными процессами и организации надёжных вычислений. Это определение применимо к большинству современных ОС общего назначения.

Прикрепленные файлы: 1 файл

Отчет ОМТ.docx

— 74.67 Кб (Скачать документ)

 

 ASSUME    SS:@stack,DS:@data,CS:@code

 

; ==== Макросы =====

; очистка экрана

clear    MACRO

 MOV AX, 03h

 INT 10h

ENDM

 

; переводит каретку  на новую строку

nl    MACRO

 MOV    AH,2h

 MOV    DL,10

 INT    21h

 MOV    DL,13

 INT    21h

ENDM

 

 

; ==== Процедуры =====

 

 

 

; выводит на экран  строку, указанной длины

; @param STACK 1 - смещение  начала строки

puts    PROC    NEAR

 MOV    BX,SP

 MOV    DX,SS:BX[2]                ; смещение строки

 MOV    BX,DX                    ; для адресации по базе используем тот же BX

 ADD    DX,2                    ; смещаемся на единицу, т. е. первые байты - длина p-строки

 MOV    CX,[BX][0]                ; длина строки хранится в первом байте

 MOV    BX,1

 MOV    AH,40h

 INT    21h

 RET    2

ENDP

 

; сравнивает число  с нулём, аварийно завершает  программу если выполняется деление  на ноль

; @param STACK 1 - делимое

c_zero    PROC    NEAR

 MOV    BX,SP

 MOV    AX,SS:[BX][2]

if_zer1:

 CMP    AX,0

 JE    ifdo_zer1

 JMP    endif_zer1

ifdo_zer1:

 PUSH    OFFSET div_zer

 CALL    puts

 JMP    exit

endif_zer1:

 

 RET 2

ENDP

 

; ввод строки с  клавиатуры, изменяет длину строки  на реально введённую пользователем.  Возможны потери памяти при  избыточном буфере

; @param STACK 1 - начало  строки

gets    PROC    NEAR

 MOV    BX,SP

 MOV    DX,SS:BX[2]                ; смещение строки

 MOV    BX,DX                    ; для адресации по базе используем тот же BX

 ADD    DX,2                    ; смещаемся на единицу, т. е. первые байты - длина p-строки

 MOV    CX,[BX][0]                ; длина строки хранится в первом байте

 ADD    CX,2                    ; учитываем возможный ввод последних символов 10,13

 MOV    BX,0

 MOV    AH,3Fh

 INT    21h

 

 MOV    BX,SP

 MOV    DX,SS:BX[2]

 MOV    BX,DX

 SUB    AX,2                    ; не учитываем перенос строки

 MOV    [BX][0], AX                ; изменяем первый байт p-строки

 RET    2

ENDP

 

; возвращает абсолютное  значение числа и его знак

; @param STACK 1 - число  под модулем

; @return STACK 1 - модуль  числа

; @return STACK 2 - знак числа

absl    PROC    NEAR

 MOV    BX,SP                ; для индексирования по базе

 MOV    AX,SS:BX[2]            ; операнд

 

if_abs:

 CMP    AX,0            ; узнаём знак числа

 JNS    else_abs        ; если не отрицательное, пропускаем

ifdo_abs:

 MOV    DX,1

 MOV    SS:BX[4], DX        ; ставим флаг отрицательного числа

 NEG    AX            ; получаем модуль числа

 MOV    SS:BX[2],AX        ; возвращаем параметры

 JMP    endif_abs

else_abs:

 MOV    DX,0

 MOV    SS:BX[4],DX        ; ставим флаг положительного числа

endif_abs:

 RET

ENDP

 

; переводит число  в строковый эквивалент, изменяет  строку начиная с переданного  смещения

; @param STACK 1 - число

; @param STACK 2 - смещение  строки

i_to_s    PROC    NEAR

 LOCAL    nbase:WORD,is_neg:WORD        ; основание числа, флаг негативного числа

 MOV    nbase,10

 

 MOV    BX,SP

 

 PUSH    0                ; резервируем место для возврата данных

 MOV    AX,SS:[BX][2]

 PUSH    AX                ; передаём число

 CALL    absl

 POP    AX                ; модуль числа

 POP    is_neg                ; возвращённый знак числа

 

 MOV    EDX,ESP

 MOV    BX,SS:[EDX][4]            ; смещение строки

 MOV    SI,[BX][0]            ; длина строки

 ADD    BX,2                ; начало рабочей области строки

 

while_is1:                    ; начало заголовка цикла ~СИ: while(SI)

 CMP    SI,0

 JE    endwhile_is1

whiledo_is1:                    ; начало тела цикла

 

 if_3:

 CMP    SI,[BX][-2]        ; проверка, если это первый символ

 JE    else_3            ; то в любом случае выводим цифру

 CMP    AX,0            ; если число делимое равно 0, то добавляем пробелы или знак минуса

 JNE    else_3

 

 

ifdo_3:

if_2:                ; если разрады числа закончились, выводим пробел или знак минус

 CMP    is_neg,0    ; если число было отрицательным, добавляем знак минуса

 JE    else_2

ifdo_2:

 MOV    is_neg,0    ; зануляем для предотвращения последующих выводов '-'       

 MOV    DX,'-'        ; конкатенуем знак минуса

 JMP    endif_2                       

else_2:

 MOV    DX,' '        ; ставим пробел

endif_2:

 

 JMP endif_3

else_3:

 XOR    DX,DX            ; зануляем DX

 MOV    CX,nbase   

 DIV    CX            ; делим на 10, остаток в DX

 OR    DL,30h            ; превращаем в цифровой символ

endif_3:

 

 DEC    SI                ; сначала уменьшаем итератор, т. е. последний символ - длина-1

 MOV    [BX][SI],DL            ; копируем символ в строку, учитывая что это p-строка

 

 JMP    while_is1

endwhile_is1:                    ; конец цикла

 

 RET    4

ENDP

 

 

; конвертирует строку  в соответствующее ей число,  учитывая знак и возможные  лишние пробелы/табуляции

; @param STACK 1 - смещение p-строки

; @return STACK 1 - полученное  число

s_to_i    PROC    NEAR

 LOCAL    nbase:WORD,num_b:WORD,c_mul:WORD

 MOV    nbase,10             ; инициализация основания числа

 MOV    c_mul,1                ; текущий множитель

 MOV    DI,0                ; результирующее число

 

 MOV    EAX, ESP           

 MOV    BX,SS:[EAX][2]            ; инициализируем базу для работы со строкой

 MOV    SI,[BX][0]

 ADD    BX,2

 

 ; преобразуем каждый символ

while_si2:

 CMP    SI,0                ; ~СИ: while(SI){...}

 JE    endwhile_si2

whiledo_si2:

 DEC    SI                ; сдвигаемся по строке к началу

 MOV    AX,[BX][SI]            ; получаем очередной символ

 XOR    AH,AH

 

if_si1:                    ; если работаем с последним символом и это знак минуса

 CMP    SI,0

 JNE    else_si1

 CMP    BYTE PTR [BX][SI],'-'

 JNE    else_si1

ifdo_si1:

 NEG    DI            ; отрицаем число

 JMP    endif_si1

 else_si1:

 XOR    AX,30h            ; переводим в эквивалент - цифру

 MUL    c_mul            ; умножаем на текущую степеть базы

 ADD    DI,AX

 MOV    AX,c_mul

 MUL    nbase

 MOV    c_mul,AX        ; следующая степень базы

 endif_si1:

 

 JMP    while_si2

endwhile_si2:

 

 MOV    BX,SP

 MOV    SS:BX[2],DI

 

 RET

ENDP

 

 

main:   

 MOV    AX, @data

 MOV    DS, AX

 

clear                    ; очищаем экран

 

 PUSH    OFFSET msg1

 CALL    puts

 MOV    SI,OFFSET a            ; указатель на первый операнд в массиве

 MOV    CX,4                ; вводим 4 операнда

do_1:

 PUSH    CX                ; сохраняем счётчики, т. к. будет затёрты функциями

 PUSH    SI

 

 PUSH    OFFSET str_c            ; получаем строку

 CALL    gets

 

 PUSH    OFFSET str_c            ; конвертируем её в число

 CALL    s_to_i

 POP    AX

 

 POP    SI

 POP    CX

 MOV    [SI],AX                ; сохраняем операнд

 ADD    SI,2                ; смещение следующего операнда

 

 MOV    WORD PTR str_c, 4        ; восстанавливаем длину строки

 

 LOOP    do_1

enddowhile_1:

 

 PUSH    OFFSET answer

 CALL    puts

 

 ; <НАЧАЛО> вычисления a/b+c*d/(c+b)

 MOV    BX, c                ; сначала найдём BX=(c+b)

 ADD    BX, b

 PUSH    BX                ; перед проверкой делителей на 0, сохраняем пром. результат

 PUSH    BX

 

 PUSH    b

 CALL    c_zero

 

 POP    BX

 PUSH    BX

 CALL    c_zero

 

 POP    BX

 MOV    AX, a

 CWD                    ; расширяем AX до DX:AX

 

 IDIV    b                ; AX=a/b

 

 PUSH    AX                ; сохраняем промежуточный результат a/b

 

 MOV    AX,c

 IMUL    d                ; DX:AX=c*d

 

 CWD

 IDIV    BX                ; делим c*d/(c+b), результат в AX

 

 POP    DX                ; извлекаем первое слогаемое из стека

 ADD    AX, DX                ; в AX находится результат операции

 ; <КОНЕЦ> вычисления

 

 

 PUSH    OFFSET str_c

 PUSH    AX                ; конвертируемое число

 CALL    i_to_s

 

 PUSH    OFFSET str_c            ; вывод всей строки на экран

 CALL    puts

nl   

 

exit:                        ; метка выхода из программы

Информация о работе Основы микропроцессорной техники