Задание по системному программированию
Системное программирование
Задание 2
Текст задания
Задание 2.1. Первая цифра задана в AX, вторая цифра задана в BX. Написать программу, которая выводит в одну строку первую цифру, пробел, вторую цифру.
Задание 2.2. Первая цифра задана в AX, вторая цифра задана в BX. Написать программу, которая выводит в одну строку первую цифру (AX), пробел, вторую цифру (BX). Далее совершает обмен значений регистров AX и BX и снова в новой строке на экране выводит в одну строку первую цифру (AX), пробел, вторую цифру (BX). Обмен совершить без использования дополнительной памяти, регистров.
Задание 1
Текст программы
.model small
.stack 100h
.data
.code
start:
mov ax, @data
mov ds, ax
mov ax, 5
mov bx, 7
mov ah, 02h
mov dl, al
add dl, 30h
int 21h
mov dl, 0h
int 21h
mov dl, bl
add dl, 30h
int 21h
mov ax, 4C00h
int 21h
end start
Таблица трассировки
Шаг |
Машинный код |
Команда |
Регистры |
Флаги |
||||||||
AX |
BX |
CX |
DX |
SP |
DS |
SS |
CS |
IP |
CZSOPAID |
|||
0000 |
0000 |
0000 |
0000 |
0100 |
489D |
48B0 |
48AD |
0000 |
00000010 |
|||
1 |
B8B048 |
mov ax, 48B0 |
48B0 |
0000 |
0000 |
0000 |
0100 |
489D |
48B0 |
48AD |
0003 |
00000010 |
2 |
8ED8 |
mov ds, ax |
48B0 |
0000 |
0000 |
0000 |
0100 |
48B0 |
48B0 |
48AD |
0005 |
00000010 |
3 |
B80550 |
mov ax, 0005 |
0005 |
0000 |
0000 |
0000 |
0100 |
48B0 |
48B0 |
48AD |
0008 |
00000010 |
4 |
BB0700 |
mov bx, 0007 |
0005 |
0007 |
0000 |
0000 |
0100 |
48B0 |
48B0 |
48AD |
000B |
00000010 |
5 |
B402 |
mov ah, 02 |
0205 |
0007 |
0000 |
0000 |
0100 |
48B0 |
48B0 |
48AD |
000D |
00000010 |
6 |
8AD0 |
mov dl, al |
0205 |
0007 |
0000 |
0005 |
0100 |
48B0 |
48B0 |
48AD |
000F |
00000010 |
7 |
80C230 |
add dl, 30 |
0205 |
0007 |
0000 |
0035 |
0100 |
48B0 |
48B0 |
48AD |
0012 |
00001010 |
8 |
CD21 |
int 21 |
0235 |
0007 |
0000 |
0035 |
0100 |
48B0 |
48B0 |
48AD |
0014 |
00001010 |
9 |
B200 |
mov dl, 00 |
0235 |
0007 |
0000 |
0000 |
0100 |
48B0 |
48B0 |
48AD |
0016 |
00001010 |
10 |
CD21 |
int 21 |
0200 |
0007 |
0000 |
0000 |
0100 |
48B0 |
48B0 |
48AD |
0018 |
00001010 |
11 |
8AD3 |
mov dl, bl |
0200 |
0007 |
0000 |
0007 |
0100 |
48B0 |
48B0 |
48AD |
001A |
00001010 |
12 |
80C230 |
add dl, 30 |
0200 |
0007 |
0000 |
0037 |
0100 |
48B0 |
48B0 |
48AD |
001D |
00000010 |
13 |
CD21 |
int 21 |
0237 |
0007 |
0000 |
0037 |
0100 |
48B0 |
48B0 |
48AD |
001F |
00000010 |
14 |
B8004C |
mov ax, 4C00 |
4C00 |
0007 |
0000 |
0037 |
0100 |
48B0 |
48B0 |
48AD |
0022 |
00000010 |
15 |
CD21 |
int 21 |
0192 |
000B |
F711 |
098D |
0106 |
2110 |
0192 |
0000 |
0000 |
10100011 |
Задание 2
Текст программы
.model small
.stack 100h
.data
.code
start:
mov ax, @data
mov ds, ax
mov ax, 5
mov bx, 7
mov dl, al
call print
mov dl, 0D0h
call print
mov dl, bl
call print
mov dl, 0DDh
call print
mov dl, 0DAh
call print
xchg ax, bx
mov dl, al
call print
mov dl, 0D0h
call print
mov dl, bl
call print
mov ax, 4C00h
int 21h
print proc
push ax
push dx
mov ah, 02h
add dx, 30h
int 21h
pop dx
pop ax
ret
print endp
end start
Таблица трассировки
Шаг |
Машинный код |
Команда |
Регистры |
Флаги |
||||||||
AX |
BX |
CX |
DX |
SP |
DS |
SS |
CS |
IP |
CZSOPAID |
|||
0000 |
0000 |
0000 |
0000 |
0100 |
489D |
48B2 |
48AD |
0000 |
00000010 |
|||
1 |
B8B248 |
mov ax, 48B2 |
48B2 |
0000 |
0000 |
0000 |
0100 |
489D |
48B2 |
48AD |
0003 |
00000010 |
2 |
8ED8 |
mov ds, ax |
48B2 |
0000 |
0000 |
0000 |
0100 |
48B2 |
48B2 |
48AD |
0005 |
00000010 |
3 |
B80500 |
mov ax, 0005 |
0005 |
0000 |
0000 |
0000 |
0100 |
48B2 |
48B2 |
48AD |
0008 |
00000010 |
4 |
BB0700 |
mov bx, 0007 |
0005 |
0007 |
0000 |
0000 |
0100 |
48B2 |
48B2 |
48AD |
000B |
00000010 |
5 |
8AD0 |
mov dl, al |
0005 |
0007 |
0000 |
0005 |
0100 |
48B2 |
48B2 |
48AD |
000D |
00000010 |
6 |
E82900 |
call 0039 |
0005 |
0007 |
0000 |
0005 |
0100 |
48B2 |
48B2 |
48AD |
0010 |
00001010 |
7 |
E2D0 |
mov dl, D0 |
0005 |
0007 |
0000 |
00D0 |
0100 |
48B2 |
48B2 |
48AD |
0012 |
00001010 |
8 |
E82400 |
call 0039 |
0005 |
0007 |
0000 |
00D0 |
0100 |
48B2 |
48B2 |
48AD |
0015 |
00001010 |
9 |
8AD3 |
mov dl, bl |
0005 |
0007 |
0000 |
0007 |
0100 |
48B2 |
48B2 |
48AD |
0017 |
00001010 |
10 |
E81F00 |
call 0039 |
0005 |
0007 |
0000 |
0007 |
0100 |
48B2 |
48B2 |
48AD |
001A |
00000010 |
11 |
B2DD |
mov dl, DD |
0005 |
0007 |
0000 |
00DD |
0100 |
48B2 |
48B2 |
48AD |
001C |
00000010 |
12 |
E81A00 |
call 0039 |
0005 |
0007 |
0000 |
00DD |
0100 |
48B2 |
48B2 |
48AD |
001F |
00000010 |
13 |
B2DA |
mov dl, DA |
0005 |
0007 |
0000 |
00DA |
0100 |
48B2 |
48B2 |
48AD |
0021 |
00000010 |
14 |
E81500 |
call 0039 |
0005 |
0007 |
0000 |
00DA |
0100 |
48B2 |
48B2 |
48AD |
0024 |
00001010 |
15 |
93 |
xchg bx, ax |
0007 |
0005 |
0000 |
00DA |
0100 |
48B2 |
48B2 |
48AD |
0025 |
00001010 |
16 |
8AD0 |
mov dl, al |
0007 |
0005 |
0000 |
0007 |
0100 |
48B2 |
48B2 |
48AD |
0027 |
00001010 |
17 |
E80F00 |
call 0039 |
0007 |
0005 |
0000 |
0007 |
0100 |
48B2 |
48B2 |
48AD |
002A |
00000010 |
18 |
B2D0 |
mov dl, D0 |
0007 |
0005 |
0000 |
00D0 |
0100 |
48B2 |
48B2 |
48AD |
002C |
00000010 |
19 |
E80A00 |
call 0039 |
0007 |
0005 |
0000 |
00D0 |
0100 |
48B2 |
48B2 |
48AD |
002F |
00001010 |
20 |
8AD3 |
mov dl, bl |
0007 |
0005 |
0000 |
0005 |
0100 |
48B2 |
48B2 |
48AD |
0031 |
00001010 |
21 |
E80500 |
call 0039 |
0007 |
0005 |
0000 |
0005 |
0100 |
48B2 |
48B2 |
48AD |
0034 |
00001010 |
22 |
B8004C |
mov ax, 4C00 |
4C00 |
0005 |
0000 |
0005 |
0100 |
48B2 |
48B2 |
48AD |
0037 |
00001010 |
23 |
CD21 |
int 21 |
0192 |
000C |
F711 |
098D |
0106 |
2110 |
0192 |
0000 |
0000 |
10100011 |
Контрольные вопросы
1. Объясните назначение процедуры. Когда процедура определяется как near? Когда процедура определяется как far? Как определяются начало и конец процедуры?
Ответ: Процедуры необходимы для разбиения программы на отдельные модули. Процедура near подразумевает вызов процедуры только внутри сегмента, где она объявлена. Far процедура может быть вызвана из любого сегмента программы. Описание процедуры имеет следующий синтаксис:
<имя_процедуры> PROC <параметр>
<тело_процедуры>
RET ;Возврат из подпрограммы в точку вызова
<имя_процедуры> ENDP
2. Ваша программа состоит из главной процедуры и процедур-подпрограмм. Каким может быть взаимное расположение главной процедуры и подпрограмм?
Ответ: Процедура подпрограмма может располагаться в конце сегмента кода или внутри основной процедуры. Также возможно выделить для подпрограммы отдельный кодовый сегмент.
3. Дайте определения понятиям точка возврата и адрес возврата.
Ответ: Для ближней процедуры адрес возврата — это смещение точки возврата относительно текущего кодового сегмента, записанное в слове. Для дальней процедуры адрес возврата — это слово, содержащее адрес сегмента, в котором расположена точка возврата и слово, содержащее смещение точки возврата внутри этого сегмента. Точка возврата — команда, которой будет передано управление после завершения процедуры.
4. Используя данные из таблиц трассировки, объясните из чего состоит код команды call. Что делает процессор при выполнении команды call?
Ответ: Команда call имеет шаблон call <адрес возврата>, где адрес возврата – это значение IP. При выполнении команды call процессор заносит в стек адрес возврата и меняет IP.
5. Какой машинный код имеет команда ret в зависимости от того является она командой retn или retf? Что делает процессор при выполнении команды ret (retn или retf)?
Ответ: Retn считывает из стека слово и загружает его в IP, выполняя тем самым действия, обратные ближнему вызову процедуры командой call. Команда retf загружает из стека IP и CS, возвращаясь из дальней процедуры. Если в программе указана команда ret, ассемблер заменит ее на retn или retf в зависимости от того, как была описана процедура, которую эта команда завершает. Машинный код для команды retn – C3, для renf – CB.
6. Какими способами можно завершить работу программы?
Ответ: Можно использовать последовательность команд:
mov ax, 4C00h
int 21h
Или использовать ret в главной процедуре.