====== Урок 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