
- •Связь Ассемблера и Си
- •Void main()
- •Ограничения на встроенное ассемблирование.
- •Вызов функций, написанных на языке Ассемблера из Си-программ
- •Передача параметров в функциях Си
- •Вызов функций Си из программ на языке Ассемблера
- •Include macro.Inc
- •If type number eq 0
- •If number le 0fffFh
- •X dw 0fcd5h
- •Void main()
Связь Ассемблера и Си
Большие программы целиком на языке Ассемблера разрабатываются редко. Обычная практика такова. Те части программы, быстродействие которых критично, переписываются на языке Ассемблера. Например для формирования изображения на экране дисплея эффективно использование строковых команд, быстро записывающих информацию в видеопамять. На языке Ассемблера пишут команды обращения к аппаратуре компьютера.
Мы рассмотрим две возможности стыковки Си и Ассемблера: использование команд на языке Ассемблера прямо в тексте программы, написанной на языке Си, и вызов из программы на языке Си подпрограммы, написанной на языке ассемблера.
Встроенный ассемблерный код.
Рассмотрим самый простой пример
#include <stdio.h>
Void main()
{ int TestValue;
printf("Input TestValue\n");
scanf("%d", &TestValue);
asm inc word ptr TestValue
printf("Incremented %d\n",TestValue);
}
Ключевое слово asmозначает, что за ней следует строка на языке Ассемблера. Точку с запятой — разделитель операторов в языке Си — ставить не нужно. Вызывает удивление присутствие атрибутного оператораword ptr. Зачем он нужен, если в тексте программы указано, что TestValue имеет типint.
Воспользуемся компилятором командной строки.
tcc -B incr.c
Ключ -BозначаетCompileviaassemble— компиляция посредством ассемблирования. Файлincr.cпреобразуется во временный файлincr.asm. Далееtccвызывает ассемблерtasm.exe, который создаёт объектный файл. Далее вызывается компоновщик.tccдолжен знать, где находитсяtasm. Поэтому, если кtasm.exeне "проложено дорожки" (path), то её нужно явно указать в файлеturboc.cfg, расположенном в текущей директории. Для нашего ВЦ этот файл должен быть таким
turboc.cfg |
|
-Ie:\tc_2plus\include |
путь к включаемым файлам |
-Le:\tc_2plus\lib |
путь к библиотекам |
-Ee:\tasm\tasm.exe |
внешний ассемблер |
Вместо ключа -Bможно было вставить в текст программы в качестве первой строки директиву #pragmainline.
Как посмотреть сгенерированный ассемблерный код. Для этого укажем ключ -S — produce assemble output.
tcc -S incr.c
Тогда на диске создаётся файл incr.asm. В нём находим строку
inc word ptr [bp-2]
Переменная TestValueсоздаётся в автоматической памяти, т.е. в стеке. Как мы видели ранее, такие переменные адресуются с помощьюbp, причём отсчёт идёт в сторону уменьшения адресов. В приведенной выше команде атрибутный оператор необходим, т.к. неясно, на что ссылаетсяbp-2 — на слово или байт.
Ключ -Sполезен для изучения ассемблерного аналога исходного текста на языке Си. Но можно обойтись и без него.
В BorlandC++ 3.1 появился встроенный (built-in) ассемблер. Если не указать ключ -Bпри вызовеbcc, то используется именно он. Встроенный ассемблер не использует макросов, режимаIDEAL, инструкций 386-го процессора (впрочем, уже естьBorlandC++ 5.01).
Начиная с BorlandC++ 3.1 можно заключать группу ассемблерных команд в фигурные скобки и помещать перед ними ключевое словоasm.
Ограничения на встроенное ассемблирование.
Команды перехода могут ссылаться только на метки Си
правильно |
неправильно |
asm jz NoDec asm dec cx NoDec: … |
asm jz NoDec asm dec cx asm NoDec: … |
Остальные команды могут иметь любые операнды кроме меток Си
правильно |
неправильно |
asm val db '0' … asm mov al, val |
val: asm db '0' … asm mov al, val |
В начале ассемблерного фрагмента нужно сохранять, а в конце восстанавливать регистры BP,SP,CS,DS,SS(разумеется, если они претерпевают изменения). Если возникают сомнения, полезно использовать ключ -Sи смотреть ассемблерный код в целом.
Недостатки встроенного ассемблерного кода
компилятор не оптимизирует код текста программы на Си,
нет мобильности (нельзя перенести программу на другой тип процессора),
медленнее выполняется компиляция,
затруднена отладка.
В VisualC++ 6.0 используется ключевое слово__asm(обратите внимание, чтоasmпредшествует два символа подчёркивания).