Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Лекции / GL17.doc
Скачиваний:
24
Добавлен:
20.05.2014
Размер:
81 Кб
Скачать

Вызов функций, написанных на языке Ассемблера из Си-программ

Предположим, у нас есть файл с главной программой на языке Си prim.cи файл с подпрограммой на языке Ассемблераsub.asm. Их трансляция и компоновка из командной строки осуществляется командой

tcc prim.c sub.asm

Тогда для файла prim.c вызывается компилятор Си образуется файл prim.obj. Для файла sub.asm вызывается tasm.exe и образуется sub.obj. Наконец, вызывается компоновщик tlink, который из объектных файлов создаёт загрузочный (исполняемый) файл prim.exe.

Сделаем важное замечание. При трансляции программы на языке Ассемблера её текст приводится к верхнему регистру и поэтому такие, например, имена, как Testиtestнеразличимы. Но в программе на языке Си такие имена различны. Поэтому при ассемблировании можно указать дляtasmключи, которые сделают имена различимыми.

Если запустить tasm.exeбез хвоста командной строки, то на экран будет выведена краткая справка по ключамtasm. Одна из строк такова

/ml,/mx,/mu Case sensitivity on symbols: ml=all, mx=globals, mu=none

/mu— преобразование всех имён к верхнему регистру (по умолчанию)

/ml— имена различаются регистром (мнемоники команд и директив это не касается:Movиmovнеразличимы)

/mx— различие в регистре только для глобальных имён.

tccавтоматически вызываетtasmс ключом /ml. Если пользователь хочет, чтобы чувствительность к регистру была только для глобальных имён, то следует применить команды

tasm /mx sub.asm

tcc prim.c sub.obj

Передача параметров в функциях Си

Описание функции выглядит так

тип_результата имя_функции(тип_параметра_1, тип_параметра_2, …)

Соответственно, вызов функции имеет вид

[возвращаемое_значение = ] имя_функции(параметр_1, параметр_2, …);

Для дальнейшего изложения введём обозначение v=f(p1,p2,…,pn).

Вызывающая программа начинает формировать стековый кадр, помещая параметры в стек справа налево. При переходе в подпрограмму в стеке запоминается адрес возврата (в малой модели памяти это одно слово). В подпрограмме необходимо выполнить команды

push bp

mov bp, sp

После этого стековый кадр приобретает вид (в предположении, что каждый параметр занимает слово)

bp

старое BP

адрес возврата

bp + 4

p1

bp + 6

p2

bp + 2 + 2*n

pn

После выполнения тела подпрограммы нужно выполнить команды

mov sp, bp

pop bp

ret

Уничтожением стекового кадра занимается вызывающая программа. В ней выполняется команда

add sp, 2*n, гдеn— количество параметров.

Теперь вам должно быть понятно, почему, если мы хотим, чтобы подпрограмма изменила значения переменной, то в качестве параметра нужно использовать адрес этой переменной. Дело в том, что содержимое стекового кадра немедленно уничтожается после того как функция отработала.

На рисунке изображён стековый кадр, где каждый параметр занимает слово. Можно передавать и двойные слова и другие данные (например, плавающее число с двойной точностью занимает 8 байтов).

Для возвращаемого значения действует очень простое правило. Если возвращаемое значение слово, то результат в регистре AX, если двойное слово — в пареDX:AX. Исключение составляют плавающие числа, но мы их не рассматриваем.

Соседние файлы в папке Лекции