- •Введение
- •1 Теоретический раздел
- •Основные сведения о языке Ассемблер
- •Организация подпрограмм в языке Ассемблер
- •Способы передачи параметров в подпрограммах
- •1.3.1 Передача параметров через регистры
- •1.3.2 Передача параметров через стек
- •Практический раздел
- •Постановка задачи
- •Описание решения задачи
- •Тестирование программы
- •Заключение
- •Список литературы
1.3.2 Передача параметров через стек
Перед вызовом процедуры все параметры заносятся в стек. Размещенные параметры удаляются из стека внутри вызываемой или вызывающей процедуры, так же можно использовать директиву RET n.
Что делать, если подпрограмма и сама активно использует стек? Для того что бы иметь доступ к сохраненным в стеке аргументам, необходимо в начале вызываемой процедуры сохранить в регистре bp адрес вершины стека для этого пишут пролог:
push bp
mov bp, sp
Теперь можно обращаться в аргументам в стеке относительно адреса, хранящегося в bp. Важно при этом помнить, что команда вызова процедуры САLL поместит на верхушку стека значение ip или ip и cs в зависимости от типа вызываемой подпрограммы.
Для восстановления состояния стека до его использования подпрограммой, необходимо загрузить в регистр sp адрес хранящийся в bp (написать эпилог):
mov sp, bp
pop bp
Необходимо помнить, что поверх параметров, передаваемых в подпрограмму, в стек записываются командой call одно или два слова адреса возврата. Каждая процедура «знает» свой тип вызова (одно или два слова) и отступив от верхушки стека на +2 или на +4 читает параметры.
mov ax, bp+2 ; первый параметр при ближнем вызове
mov ax, bp+4 ; первый параметр при дальнем вызове.
Практический раздел
Постановка задачи
Разработать две подпрограммы, одна из которых преобразует любую заданную букву в заглавную (в том числе для русских букв), а другая преобразует букву в строчную. Разработать программу, которая вводит с клавиатуры строку и замещает первые буквы всех слов заглавными, а остальные строчными буквами.
Описание решения задачи
include io.asm
data segment
max db 100
kolvo db ?
stroka db 100 dup(?)
smallen db 'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'
bigen db 'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z'
smallru db 'а','б','в','г','д','е','ё','ж','з','и','й','к','л','м','н','о','п','р','с','т','у','ф','х','ц','ч','ш','щ','ъ','ы','ь','э','ю','я'
bigru db 'А','Б','В','Г','Д','Е','Ё','Ж','З','И','Й','К','Л','М','Н','О','П','Р','С','Т','У','Ф','Х','Ц','Ч','Ш','Щ','Ъ','Ы','Ь','Э','Ю','Я'
kolvo2 db ?
data ends
code segment
assume cs:code,ds:data
ups proc
push cx ; сохранение регистров в стек
push dx
push ax
mov dl,[bx]
push bx
xor cx,cx ; обнуление cx
cmp dl,'z'
jng smen
jmp m1
smen: mov cl,26
lea bx,smallen
povtor1:mov al,[bx]
cmp dl,al
jz uv
jmp m2
uv: mov dl,[bx+26]
mov cx,0001h
jmp m101
m2: inc bx
loop povtor1
m1: cmp dx,'я'
jng smru
jmp m101
smru: mov cl,31
lea bx,smallru
povtor3: mov al,[bx]
cmp dl,al
je uvr
jmp m6
uvr: mov dl,[bx+31]
mov cx,0001h
m6: inc bx
loop povtor3
m101: mov dh,00h
xor bx,bx
pop bx
mov [bx],dl
xor dx,dx
xor ax,ax
xor cx,cx
pop ax
pop dx
pop cx
ret
ups endp
downs proc
push cx
push dx
push ax
mov dl,[bx]
push bx
xor cx,cx
cmp dl,'Z'
jng ben
jmp m3
ben: mov cx,26
lea bx,bigen
povtor2: mov al,[bx]
cmp dl,al
je me
jmp m4
me: mov al,[bx-26]
mov dl,al
mov cx,0001h
jmp m102
m4: inc bx
loop povtor2
m3: cmp dl,'Я'
jng bur
jmp m102
bur: mov cl,31
lea bx,bigru
povtor4: mov al,[bx]
cmp dx,ax
je mu
jmp m8
mu: mov al,[bx-31]
mov dl,al
mov cx,0001h
m8: inc bx
loop povtor4
m102:mov dh,00h
xor bx,bx
pop bx
mov [bx],dl
xor dx,dx
xor ax,ax
xor cx,cx
pop ax
pop dx
pop cx
ret
downs endp
start: mov ax,data
mov ds,ax ;загрузить сегментный адрес данных
lea dx,max ; заносим в регистр dx
mov ah,0ah ;функция ввода строки с клавиатуры
int 21h ; вывод на экран
xor ax,ax ; обнуление
lea bx,kolvo ; заносим в регистр bx
mov cl,[bx] ;в cl записывается начала массива [bx]
mov kolvo2,cl ; в регистр записывается kolvo2
mov kolvo,' ' ; в kolvo записывается пробел
lea bx,kolvo ; заносится в регистр bx
beg: mov al,[bx] ;в al записывается начала массива [bx]
cmp al,' ' ;сравнение al с пробелом
jz rav
call downs
jmp m21
rav: inc bx
call ups
dec cx
m21: inc bx
loop beg
lea bx,kolvo2
mov al,[bx]
mov bl,al
mov word ptr [bx+2], '$'
mov dl,0ah
mov ah,02h
int 21h
lea dx,stroka
mov ah,09h
int 21h
mov ah,01h
int 21h
QUIT: mov ax,4c00h
int 21h
code ends
end start
