- •5. Препроцессор. Директивы препроцессора.
- •7.Работа с файлами. Текстовый и двоичный режим.
- •10.Перечислимый тип. Структуры. Объединения.
- •13.Спецификаторы класса памяти.
- •14.Пространства имён.
- •16.Понятие класса.
- •17.Функции-члены класса. Указатель this.
- •18.Конструкторы. Деструкторы.
- •19.Преобразования объектов класса.
- •20.Доступ к членам класса.
- •21.Статические члены класса.
- •23.Совместное использование.
- •27.Производные классы.
- •29.Указатели на члены класса.
- •30.Множественное наследование.
- •31.Структура dll-библиотеки.
- •32.Статическое и динамическое подключение dll-библиотек.
- •34.Регистры процессора.
- •36.Арифметические команды в языке ассемблера.
- •37.Команды сравнения и перехода в языке ассемблера.
- •38.Команды работы с битами в языке ассемблера.
- •39.Процедуры в языке ассемблера. Передача параметров в процедуру.
- •40.Процедуры в языке ассемблера. Возврат результата. Локальные данные.
40.Процедуры в языке ассемблера. Возврат результата. Локальные данные.
Передача результата процедуры
Для передачи результата процедуры обычно используется регистр EAX. Этот способ используется не только в программах на языке ассемблера, но и в программах на языке С++. Объекты, имеющие размер не более 8 байт, могут передаваться через регистровую пару EDX:EAX. Вещественные числа передаются через вершину стека вещественных регистров. Если эти способы не подходят, то следует передать в качестве параметра адрес ячейки памяти, куда будет записан результат.
; Передача параметров через стек, возврат результата через регистр EAX
.686
.model flat, c
option casemap: none
include \masm32\include\windows.inc
include \masm32\include\kernel32.inc
includelib \masm32\lib\kernel32.lib
.data
a dd 76
b dd -8
c dd ?
.code
program:
push b ; Кладём параметры в стек
push a
call Procedure
add esp, 8 ; Освобождаем 8 байт стека
mov c, eax ; c = a – b
push 0
call ExitProcess
Procedure proc
mov eax, [esp + 4] ; Заносим в регистр EAX первый параметр
mov edx, [esp + 8] ; Заносим в регистр EDX второй параметр
sub eax, edx ; В регистре EAX получилась разность параметров
ret
Procedure endp
end program
; Передача параметров через стек, возврат результата по адресу
.686
.model flat, c
option casemap: none
include \masm32\include\windows.inc
include \masm32\include\kernel32.inc
includelib \masm32\lib\kernel32.lib
.data
a dd 76
b dd -8
c dd ?
.code
program:
push offset c ; Кладём в стек адрес переменной, куда будет записан результат
push b
push a
call Procedure
add esp, 8 ; Освобождаем 8 байт стека
push 0
call ExitProcess
Procedure proc
mov eax, [esp + 4] ; Заносим в регистр EAX первый параметр
mov edx, [esp + 8] ; Заносим в регистр EDX второй параметр
sub eax, edx ; В регистре EAX получилась разность параметров
mov edx, [esp + 12] ; Заносим в регистр EDX третий параметр – адрес результата
mov [edx], eax ; Записываем результат по адресу в регистре EDX
ret
Procedure endp
end program
Локальные данные процедур
Процедуры часто нуждаются в локальных данных. Локальные переменные размещаются в стеке. Для того чтобы отвести место под локальные переменные в процедуре на языке ассемблера, достаточно просто вычесть из регистра ESP размер требуемой памяти. После этого все вызываемые процедуры будут «знать», что место в стеке занято, и размещать свои данные в незанятой части стека.
При вызове других процедур, а также в ходе выполнения текущей процедуры в стек могут быть положены другие данные. При этом значение регистра ESP изменится. Поэтому регистр ESP не является надёжной точкой отсчёта для адресов локальных переменных. Для того чтобы получить такую точку отсчёта, значение регистра ESP переписывают в регистр EBP, предварительно сохранив значение регистра EBP в стеке. В этом случае регистр EBP отмечает часть стека, занятую на момент начала работы процедуры (отсюда происходит название регистра EBP – указатель базы кадра стека). При таком подходе первый параметр процедуры всегда находится по адресу [EBP + 8]. Адреса локальных переменных отсчитываются от регистра EBP с отрицательным смещением. По окончании работы процедуры значение регистра ESP восстанавливается по регистру EBP, а значение регистра EBP – из стека.
