Автор работы: Пользователь скрыл имя, 17 Января 2012 в 13:41, курсовая работа
Операционная система, сокр. ОС (англ. operating system) — комплекс управляющих и обрабатывающих программ, которые, с одной стороны, выступают как интерфейс между устройствами вычислительной системы и прикладными программами, а с другой стороны — предназначены для управления устройствами, управления вычислительными процессами, эффективного распределения вычислительных ресурсов между вычислительными процессами и организации надёжных вычислений. Это определение применимо к большинству современных ОС общего назначения.
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:
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: ; метка выхода из программы