Assembler psp что это
Обновлено: 07.07.2024
Операционная система MS DOS предъявляет некоторые обязательные требования к структуре ASM-программы, предназначенной для последующего создания EXE-файла:
l Программа может использовать 4 сегмента памяти, начальные адреса которых должны быть загружены в регистры микропроцессора CS, SS, DS и ES, а сами сегменты в явном виде определены в программе в виде операторных скобок: имя_сегмента segment . имя_сегмента ends (версии MS DOS 4.0 и выше допускают более простое указание сегментов в программе: имя_сегмента).
l В программе должно быть указание, какие сегментные регистры закрепляются за используемыми сегментами памяти; при исполнении программы сегментные регистры CS, SS, ES в соответствии с этими указаниями загружаются автоматически.
l Сегмент данных DS в EXE-программе не может быть загружен автоматически, поскольку он используется программным загрузчиком для формирования начального адреса служебной области памяти — префикса программного сегмента (PSP), непосредственно предшествующего любой исполняемой программе EXE. Регистр сегмента данных DS должен быть инициирован принудительно — для этого следует в самом начале ASM-программы записать в стек вектор-адрес возврата к служебной области PSP: содержимое регистра DS и нулевое смещение, а затем в регистр DS загрузить адрес сегмента данных. PSP — это группа служебных слов в оперативной памяти, формируемая для каждой загружаемой программы пользователя и занимающая обычно 256 байтов (100h). При запуске программы пользователя в ОЗУ автоматически формируется PSP, и ее начальный адрес помещается в регистр DS.
Типовая структура ASM-программы включает в себя:
1. Имя программы.
Может присутствовать комментарий назначения программы.
2. Инициализацию стековой памяти в сегменте стека:
STACKSEG segment stack
DW N dup(?) ; меньше 32 слов в стеке обычно задавать не следует
3. Инициализацию всех переменных в сегменте данных:
; задаются имена всех констант и переменных,
; их начальные значения и резервируется память под них
4. Назначение сегментных регистров в сегменте кодов:
Assume CS:codeseg, DS:dataseg, SS:stackseg
5. Организацию главной программной процедуры far:
6. Запись адреса префикса программного сегмента (PSP) в стек:
7. Инициализацию содержимого регистра сегмента данных:
; при указании в команде в качестве операнда символического
; имени сегмента (dataseg) происходит пересылка начального адреса
; этого сегмента — неверно указывать offset dataseg
8. Текст программы пользователя в сегменте кодов:
основной текст программы
9. Восстановление адреса PSP в DS:
10. Тексты процедур; если имеются процедуры near, используемые в данной программе, то записываются тексты этих процедур.
11. Закрытие главной процедуры main, сегмента кодов и выход из программы:
Итак, обобщенная структура программы:
; задание поля памяти для стека
; задание полей памяти для данных и определение всех констант и переменных
assume CS:codeseg, DS:dataseg, SS:stackseg
; основной текст программы
; тексты ближних процедур
Рассмотрим программу расчета сложных процентов.
Капитал Q вкладывается в некоторое мероприятие, обеспечивающее ежегодный прирост капитала D%. Задача: определить текущую величину капитала в течение первых N лет. Вот соответствующая ASM-программа для создания исполняемого EXE-файла.
TITLE | RASCHET.ASM | ; расчет сложных процентов |
STACKSG | SEGMENT | STACK 'STACK' |
DW | 64 DUP(?) | |
STACKSG | ENDS | |
DATASG | SEGMENT | 'DATA' ; задание переменных |
VVQ | DB | ' Введите величину начального капитала (до 64 000)' |
DB | 10,13,'$' | |
DB | 10,13,'Введите процент годового прироста' | |
DB | 10,13,'$' | |
VVN | DB | 10,13,'Введите количество расчетных лет' |
DB | 10,13,'$' | |
Q0 | DW | ? |
D | DW | ? |
D1 | DW | ? |
N | DW | ? |
I | DW | |
Q | DW | ? |
BUF | DB | 5, 0, 0, 0, 0, 0, 0, 0 |
VIV1 | DB | ' год капитал' |
DB | 10,13,'$' | |
SRB | DB | 14 DUP(0), '$' |
SR | DB | 6 DUP(0), '$' |
SRK | DB | 10, 13, '$' |
FT10 | DW | |
TEN | DW | |
STO | DW | |
DATASG | ENDS | |
CODESG | SEGMENT | 'CODE' |
MAIN | PROC | FAR |
ASSUME | CS:CODESG, DS:DATASG, SS:STACKSG | |
PUSH | DS | |
SUB | AX, AX | |
PUSH | AX | |
MOV | AX, DATASG | |
MOV | DS, AX | |
MOV | AH, 9 ; запрос на ввод Q | |
MOV | DX, offset VVQ | |
INT | 21H | |
MOV | AH, 0Ah ; ввод Q | |
MOV | DX, offset BUF | |
INT | 21H | |
CALL | STR2BIN | |
MOV | Q0, DI | |
MOV | AH, 9 ; запрос на ввод D | |
MOV | DX, offset VVD | |
INT | 21H | |
MOV | AH, 0AH ; ввод D | |
MOV | DX, offset BUF | |
INT | 21H | |
CALL | STR2BIN | |
MOV | D, DI | |
MOV | AH, 9 ; запрос на ввод N | |
MOV | DX, offset VVN | |
INT | 21H | |
MOV | AH, 0AH ; ввод N | |
MOV | DX, offset BUF | |
INT | 21H | |
CALL | STR2BIN | |
MOV | N, DI | |
MOV | AX, D | |
MOV | D1, AX | |
ADD | D1, 100 ; расчет D1 = (1 + D/100) * 100 | |
MOV | AX, Q0 ; присвоение Q = Q0 | |
MOV | Q, AX | |
MOV | AH, 9 | |
MOV | DX, offset VIV1 | |
INT | 21H | |
RST: | MOV | AX, Q ; расчет Q = Q * D1 |
MUL | D1 | |
DIV | STO | |
MOV | Q, AX | |
MOV | AX, I | |
CALL | BIN2STR | |
MOV | AH, 9 ; вывод года | |
MOV | DX, offset SR | |
INT | 21H | |
MOV | AH, 9 ; вывод пробела | |
MOV | DX, offset SRB | |
INT | 21H | |
MOV | AX, Q ; вывод прибыли | |
CALL | BIN2STR | |
MOV | AH, 9 | |
MOV | DX, offset SR | |
INT | 21H | |
MOV | AH, 9 ; перевод строки | |
MOV | DX, offset SRK | |
INT | 21H | |
INC | I ; I = I + 1 | |
MOV | AX, I ; сравнение I с N | |
CMP | AX, N | |
JLE | RST ; условный переход по I <= N | |
RET | ||
BIN2STR | PROC | NEAR |
MOV | SI, offset SR+5 ; процедура перевода двоичного | |
PR2: | SUB | DX, DX ; кода в код ASCII с предварительным |
MOV | [SI], DL ; обнулением поля SR | |
DEC | SI | |
CMP | SI, offset SR | |
JA | PR2 | |
MOV | CX, 10 | |
MOV | SI, offset SR+5 | |
PR1: | XOR | DX, DX |
DIV | CX | |
OR | DL, 30H | |
MOV | [SI], DL | |
DEC | SI | |
CMP | AX,0 | |
JNE | PR1 | |
RET | ||
BIN2STR | ENDP | |
STR2BIN | PROC | NEAR ; процедура перевода ASCII-кодов |
MOV | FT10, 1 ; в двоичный код | |
XOR | DI, DI | |
MOV | CX, 10 | |
LEA | SI, BUF + 1 | |
XOR | BH, BH | |
MOV | BL, [BUF + 1] | |
PR3: | MOV | AL, [SI+BX] |
AND | AX, 0FH | |
MUL | FT10 | |
ADD | DI, AX | |
MOV | AX, FT10 | |
MUL | TEN | |
MOV | FT10, AX | |
DEC | BX | |
JNZ | PR3 | |
RET | ||
STR2BIN | ENDP | |
MAIN | ENDP | |
CODESG | ENDS | |
END | MAIN |
В качестве иллюстративного примера для сравнения сложности программ на языке ассемблера с программами на языке высокого уровня, ниже приводится без пояснений программа решения этой задачи на языке Basic:
Читайте также: