Вставка в Си команд на ассемблере
Рекомендации и правила записи вставок.
1. Команда должна начинаться с ключевого слова asm. При использовании С++
несколько подряд идущих команд могут быть объединены в блок, например
asm {
.......
}
Некоторые версии трансляторов с языка СИ требуют слово asm перед каждой командой или вместо этого слова используют _asm или др.
2. Вставлять можно все допустимые машинные команды и директивы, не определяющие работу транслятора. Так не допускаются директивы
segment и ends ;
proc и endp;
assume и end
и др.
3. В ассемблерной части программы допускается использование данных Си программы всех классов (локальные, внешние, статические и регистровые). Данные могут быть объявлены в ассемблерной части программы, как внешние переменные для использования в ассемблерной части программы. Эти переменные операторы языка «С» не видят, например:
#include <iostream.h>
int y;
asm {
x dd ?
}
int main(int argc, char* argv[])
{
asm{
mov [x], 5
mov eax,[x]
mov [y],eax
}
cout << y;
char cc;
cin >> cc;
return 0;
}
Здесь показано как использовать данные, определенные в участках программы на С и на ассемблере.
4. Для некоторых версий языка С[15], если в ассемблерной части есть команда перехода, то метка записывается по правилам Си, например:
asm jmp label
............
label:asm xor ax, ax
5. Комментарии записывают по правилам Си. Символ ';' используется в качестве конца команды, а не начала комментария. В строке может быть записано несколько команд, например :
asm {push ax; push bx; push cx}
После последней или единственной команды символ ';' можно не ставить. Команды должны быть написаны по правилам MASM, не IDEAL.
6. В ассемблерной части программы нельзя изменить содержимое сегментных регистров, регистров для работы со стеком (esp, ebp), а также регистров esi, edi, если используются регистровые переменные[16].
7. Если встречается хотя бы одна ассемблерная вставка, необходим дополнительный шаг трансляции с языка Си на ассемблер. Для задания транслятору режима перевода в ассемблерный код используется директива
#pragma inline
Если директивы нет, возможна повторная трансляция, если встречена команда на ассемблере.
Ниже приведен пример программы с ассемблерными вставками
#pragma inline
#include <stdio.h>
int summa (int x, int y){
int z;
asm {
mov eax, [x]
add eax, [y]
mov [z], eax
}
return z;
}
main(){
printf(" сумма = % d\n", summa(5, 3));
}
Достоинство метода: наиболее прост с точки зрения программиста.
Недостаток метода. Нельзя отдельно оттранслировать ассемблерную часть.