
- •Архитектура ЭВМ и язык ассемблера
- •Пример
- •Директивы определения данных
- •Типы операндов (команд)
- •Пересылки простые и неочевидные
- •Директива ASSUME-специфицирует
- •Построить листинг, запустить отладчик (debug , –t, -r, u)
- •Директива ORG
- •Директива EVEN
- •Сложение и вычитание
- •Работа с данными и адресами: операторы и директивы
- •Адресация в Ассемблере
- •Адресация в Ассемблере
- •Адресация в Ассемблере
- •Адресация в Ассемблере
- •Адресация
- •Безусловный переход и цикл
- •TITLE Add and Subtract, Version 2 (AddSub2.asm)
- •Способы адресации Построить сегменты и создать exe файлы
- •Процесс создания программы
- •Учебная библиотека
- •Стек
- •Стек, использование.
- •TITLE Программа реверсирования строк
- •Определение процедур
- •Использование процедур
- •Директивы PROC и ENDP
- •Пример с процедурами
- •Пример с процедурами (продолжение)
- •Директивы MACRO,ENDM
- ••Синтаксис макроопределения
Учебная библиотека
ClrScr |
ReadHex |
CrLf |
ReadInt |
Delay |
ReadString |
DumpMem |
SetTextColor |
DumpRegs |
WaitMsg |
GetCommandTail |
WriteBin |
GetMseconds |
WriteChar |
GotoXY |
WriteDec |
Random32 |
WriteHex |
RandomiZe |
WriteInt |
ReadChar |
WriteString |
21
Стек
•Понятие стека
–LIFO (Last-In, FIst-Out)
•Стековая адресация памяти
–SS ESP
–«рост» в сторону меньших адресов
•PUSH/POP r/m16|r/m32|imm32|imm16
•PUSHFD/POPFD – флаги 32 бита
•PUHSF/POPF - флаги 16 бит
•PUSHAD/POPAD – регистры по 32 бита
EAX,ECX,EBX,ESP,EBP,ESI,EDI
• PUHSA/POPA - регистры по 16 бит
AX, CX, BX, SP, BP, SI, DI
22
Стек, использование.
PUSHF ; SP<=SP-2, [SS:SP]<=Flags POPF ; Flags<=[SS:SP]; SP<=SP+2,
•Полезно:
●Сохранение регистров
●Пересылка “без регистров”
●Доступ к элементам, BP.
•ВАЖНО:
● Баланс операций PUSH и POP
●Контроль границ
●Соглашения при передаче управления
23
TITLE Программа реверсирования строк |
(RevString.asm) |
INCLUDE Irvine32.inc |
|
.data
aName BYTE "abcdefghijklmnopqrstuvwxyz0123456789",0 nameSiZe = ($ - aName) - 1
.code main PROC
;Поместим строку посимвольно в стек mov ecx,nameSize
mov esi,0
L1: movzx eax,aName[esi] |
;Загрузим |
символ строки |
|
push |
eax |
Поместим; |
его в стек |
inc |
esi |
|
|
Loop |
L1 |
|
|
;Восстановим строку из стека в обратном порядке. mov ecx,nameSize
mov esi,0
L2: pop eax |
Загрузим; символ из |
стека |
|
mov |
aName[esi],al |
;Сохраним в массиве |
|
inc |
esi |
|
|
Loop |
L2 |
|
|
;Отобразим строку
mov edx,OFFSET aName call WriteString call CrLf
exit
main ENDP |
Пример работы со стеком |
|
END main |
||
24 |
||
|

Определение процедур
• PROC и ENDP
<имя процедуры> |
PROC <FAR|NEAR> |
|
<тело процедуры> |
<имя процедуры> |
ENDP |
•Документирование
–Целевые действия
–Ожидаемые параметры
–Возвращаемый результат
–Необходимые условия
•CALL и RET
–адрес возврата - в стеке
–CALL <имя процедуры> (адрес втолкнуть и перейти)
–RET (оказаться по вытолкнутому адресу)
25
Использование процедур
•Вложенные вызовы
•Локальные L1: и глобальные L2:: метки
•Передача параметров через регистры
•Сохранение и восстановление регистров
PROC USES reg1 reg2 …
•Функциональная декомпозиция
–Разбиение сложного действия на простые
–Автономная проверка простых действий
–Обнаружение связей и оценка их «силы»
–Разделение «структурирования» и кодирования
26
Директивы PROC и ENDP
Push |
ax;ввод в стек 3-го параметра |
|
Push |
bx;ввод в стек 2-го параметра |
|
Push |
cx;ввод в стек 1-го параметра |
|
Call |
addup:вызов процедуры |
|
Add |
cp, 6:удаление введенных в стек параметров |
|
Addup proc |
near;адрес возврата для ближнего обращения |
|
Занимает 2 байта |
||
Push |
bp;сохранение указателя основания ещё 2 байта, |
|
поэтому параметры начинаются с 4-го байта |
||
Mov |
bp, sp;загрузка стека в указатель основания |
|
Mov |
ax,[bp+4]; получение 1-го параметра |
|
Add |
ax,[bp+6] ; получение 2-го параметра |
|
Add |
ax,[bp+8] ; получение 3-го параметра |
|
Pop |
bp;восстановление основания |
Ret;возврат
Addup endp

Пример с процедурами
TITLE Программа суммирования целых чисел |
(Sum2.asm) |
|
|
; Запрашивает несколько целых чисел, сохраняет их в массиве, ; вычисляет сумму и отображает |
|||
полученный результат |
|
|
|
INCLUDE Irvine32.inc |
|
|
|
IntegerCount = 3 |
; Размер массива |
|
|
.data |
|
|
|
promptl BYTE "Введите целое число со знаком: ",0 |
pushad |
; Сохраним все регистры |
|
prompt2 BYTE "Сумма чисел равна: ",0 |
mov edx,OFFSET promptl ; Адрес приглашения |
||
array DWORD IntegerCount DUP(?) |
L1: |
|
|
.code |
|
call WriteString |
; Выведем приглашение |
mainPROC |
|
call Readlnt |
; Прочитаем число (оно в ЕАХ) |
call ClrScr |
|
mov [esi],eax |
; Запишем число в массив |
mov esi,OFFSET array |
|
add esi,4 |
; Скорректируем указатель |
mov ecx,IntegerCount |
|
; на следующий элемент массива |
|
call PromptForlntegers |
|
call CrLf |
; Перейдем на новую строку' на |
call ArraySum |
|
экране |
|
call DisplaySum |
|
loop L1 |
|
exit main ENDP |
|
popad |
; Восстановим все регистры |
;---------------------------------------------------------------- |
|
ret |
|
PromptForlntegers PROC |
|
PromptForlntegers ENDP |
;Запрашивает числа и записывает их в массив.
;Передается: ESI = адрес массива двойных слов,
;ЕСХ= размер массива.
;Возвращается: ничего
;Вызывает: Readlnt, WriteString
;--------------------------------------------------------------
28
Пример с процедурами (продолжение)
ArraySum PROC
Вычисляет сумму элементов массива 32-разрядных целых чисел Передается: ESI = адрес массива
ЕСХ = количество элементов массива Возвращается: ЕАХ = сумма элементов массива
push esi |
; Сохраним значения регистров ESI и ЕСХ |
|
push, ecx; |
|
|
mov еах,О |
; Обнулим значение суммы |
|
Ы: add eax,[esi] |
; Прибавим очередной элемент массива |
|
add |
esi,4 |
; Вычислим адрес следующего элемента массива |
loop L1 |
;Повторим цикл для всех элементов массива |
|
pop |
ecx |
; Восстановим значения регистров ESI и ЕСХ |
pop |
esi |
|
ret |
|
; Вернем сумму в регистре ЕАХ |
ArravSum EXDP ;-------------------------------------------------------------------------------
DisplavSum PROC
Отображает сумму элементов массива на экране. Передается: ЕАХ = сумма элементов массива Возвращается: ничего
Вызывает: WriteString, Writelnt ;-------------------------------------------------------------------------------
push edx
mov edx.OFFSET prompt2 ; Выведем пояснение
call WriteString |
|
call Writelnt |
; Отобразим регистр ЕАХ |
call CrLf |
|
pop edx |
29 |
DisplaySum ENDP |
|
END main |
|
org 100h
start: mov ax,13h; устанавливаем режим 320х240х256 цветов int 10h
push 0A000h; ES=0A000h начало видеопамяти в графических режимах
pop es
mov di,50*320+50; начало линий в точке Х=50 Y=50 mov al,0Fh; цвет линий
mov cx,110
rep stosb; выводим горизонтальную линию mov di,50*320+50
mov cx,100
a1: stosb; рисуем вертикальную линию add di,319
loop a1
mov di,50*320+50 mov cx,75
a2: stosb; линия под углом 45 градусов add di,320
loop a2
mov di,50*320+50 mov cx,50
a3: stosb; линия под углом 30 градусов stosb