====== Урок 0 ======
===== Адресация переменных =====
В общем случае адрес переменной или команды можно представить с помощью выражения вида База + Индекс + Смещение
где база - регистры BX или BP, индекс - регистры SI или DI. Эти регистры так и называются: базовые и индексные. Смещение - это постоянное выражение.
Пример:
Определим массив переменных greet
_DATA segment word public "DATA"
greet db 'Hello'
_DATA ends
и инициализируем ds указанием на сегмент данных
_CODE segment word public "CODE"
mov ax,_DATA
mov ds,ax
В результате выполнения следующих последовательностей команд в регистре al окажется символ 'o'((Для справки: как вывести содержимое регистра al на экран:mov ah,0eh
mov bh,0
int 10h
))
-
mov al,'o'
- mov al,[greet+4]
- mov si, (offset greet) + 4
mov al,[si]
- mov bx, offset greet + 4
mov al,[bx]
- mov bx,offset greet
mov si,4
mov al,[bx + si]
В примерах со второго по пятый в al помещался 5-й символ массива greet, в первом в al помещался символ 'o', поэтому результат всех команд одинаковый.
===== Гибридное программирование =====
Итак, пусть у нас есть программа, написанная на Си, и процедура, написанная на ассемблере. Мы хотим из программы вызвать процедуру. Для этого существует несколько условий написания и для процедуры, и для программы.
==== Идентификаторы ====
=== Си -> Ассемблер ===
Для того, чтобы процедуре были доступны переменные и функции программы, в программе их нужно объявить как принадлежащие классу //extern//, при этом в программе перед идентификатором должен стоять знак подчёркивания. При этом в процедуре эти идентификаторы должны быть объявлены с помощью директивы EXTRN
=== Ассемблер -> Си ===
Для того, чтобы программе были доступны переменные, метки и функции процедуры, необходимо в процедуре объявить данный идентификатор в директиве PUBLIC или GLOBAL, добавить в начало знак подчёркивания, а в программе объявить идентификатор как принадлежащий классу //extern//
==== Аргументы и результаты функций ====
В данном разделе кратко опишем стандарт Си-функций.
=== Результат ===
Результаты функций остаются в регистрах (один байт в AL, два байта в AX, три и четыре байта (кроме float) в DX-AX, более 4-х байт в сегменте данных с указателем в AX, результат типа double и float в верхушке стека сопроцессора).
=== Аргументы ===
Аргументы функции указываются в стеке процессора, однобайтный аргумент считается двухбайтным с неопределённым старшим байтом.
==== Примеры ====
Модуль Си:#include
extern int Fun (void);
int main ()
{
printf ("%d\n", Fun ());
return 0;
}
Модуль Ассемблер:.MODEL SMALL
PUBLIC _Fun
.CODE
_Fun PROC NEAR
MOV AX,13
RET
_Fun ENDP
END
Для компиляции программы необходимо:
- скомпилировать ассемблерный модуль в объектный с опцией /mx
- в IDE Turbo C v2.0 создать проект, в которой вписать название модуля Си и объектного модуля, полученного из ассемблерного
=== Последовательность действий для сборки гибридной программы ===
tasm //asm_module.asm// /mx
tc
**Project -> Project Name** //project.prj//
**Compile -> Make**
**File -> OS Shell** //if no errors//
//project//
=== Содержимое файла project.prj====
asm_module.obj
c_module.c