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:

Читайте также: