C/C++ и Assembler!

4 отговора 215 прегледа
#1

C/C++ и Assembler!

Как да интедрирам C++ с Assembler, т.е. в компилатора на C++ да напиша програмка на асемблер или асемблерска функция. И има ли начин за предаване на тази функция на неограничен брой параметри, например подава се броя на параметрите, те се вкарват в стек, от който се извличат от асемблерската функция, според подадения параметър???

Отговор
в отговор на Hekleramp;Koch #2

Re: C/C++ и Assembler!

Ми до колкото си спомням има една думичка asm { } или _asm { } в Visual C++, която ти дава възможност на директно вкарване на асемберски код. Другата възможност е да ползваш външен редактор за асемблер, да обявяваш направените функции като външни и да внимаваш за състоянието на регистрите и стека при изхода от външната функция. А предаването параметрите си е изцяло твоя работа, като единствено трябва да се внимава с настройките на компилатора на C++, т.к. това влияе върху дължината на предаваните типове данни.

Успех

Отговор
в отговор на ggghhhjjj #3

Re: C/C++ и Assembler!

Зависи от компилатора и трябва да се съобразяваш с (1) naming convention (2) calling style, ... трябва да знаеш как се предават параметрите.
Ако вземем VC++ и изкаш променлив брой параметри най-лесно е нещо подобно:

int __stdcall myfunc(int argnum, ...)
{
__asm {
MOV ECX, [EBP + 08H]; // първи аргумент argnum
LEA EBX, [EBP + 0CH]; // адреса на втори аргумент
XOR EAX, EAX; // нулираме EAX
CMP ECX, 0;
JE label_2; // ако argnum == 0 exit
label_1:
ADD EAX, [EBX]; // добавяме n-тия аргумент
ADD EBX, 04H; // нарастваме EBP да сочи следващия аргумент
DEC ECX;
JNZ label_1; // ако има още аргументи затваряме цикъла

label_2:
// резултата (return value) е в EAX
}
}

.

Ако извикаш myfunc(3, 1, 2, 3) получаваш 1 + 2 + 3 = 6
Ако извикаш myfunc(5, 1, 2, 3, 4, 5) получаваш 1 + 2 + 3 + 4 +5 = 15

Отговор
в отговор на ivo #4

Re: C/C++ и Assembler!

И внимавай за резервираните регистри на компилатора. За VC++ може да мажеш EAX, EDX, ECX, EBX но останалите (като ESI, EDI) трябва да ги ресторваш. Ясно е, че EBP не бива да пипаш (освен ако знаеш какво правиш). Ако използваш външен асемблер, обявяваш функцията чрез extern "C" __stdcall int myfunc(int a, ...); и в асемблера и даваш име _myfunc - това е заради naming convention.
За това, чрез __asm { ... } във VC++ e по-просто и имаш по-малки проблеми с naming convention, function prologue/epilogue, ....

После, когато връщаш int резултата е в EAX и ако връщаш double резултата е в EAX:EDX. Съобразяваш се и с дължината на аргументите, ако заемаш памет в стека после я възтановяваш естествено ...

Всичко това го пише в MSDN и човек трябва да е внимателен когато пише на асемблер.
За друг компилатор - в документацията му ще го пише.

Отговор
в отговор на i #5

Re: C/C++ и Assembler!

Благодария ви за мненията.

Отговор