Содержание

Урок 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'1)

  1. mov al,'o'
  2. mov al,[greet+4]
  3. mov si, (offset greet) + 4
    mov al,[si]
  4. mov bx, offset greet + 4
    mov al,[bx]
  5. 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 <stdio.h>
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

Для компиляции программы необходимо:

  1. скомпилировать ассемблерный модуль в объектный с опцией /mx
  2. в 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
1)
Для справки: как вывести содержимое регистра al на экран:
mov ah,0eh
mov bh,0
int 10h