Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / C++ [игнор отключен] [закрыт для гостей] / Ассемблерные вставки в c++. GNU / 25 сообщений из 35, страница 1 из 2
08.08.2005, 19:45
    #33206476
TnedutS
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Ассемблерные вставки в c++. GNU
Привет всем.
Я вот тут пытаюсь ассемблерную вставку в с++ запихнуть...
А не получается. Точнее получается... Но как - то криво.

Пишу просто для пробы:
...
void printab(int );
int x1;
asm("pushl %0\n\tcall printab \n\tpop %%eax" : : "r" (x1));
...
Пишет мне
undefined reference to printab

Смотрел в инете. Нашел, например это:

asm ("movl %0,r9\n\tmovl %1,r10\n\tcall _foo"
: /* no outputs */
: "g" (from), "g" (to)
: "r9", "r10");

Но ведь тут тоже _foo неопределена.
Это отсюда:
http://gcc.activeventure.org/Extended-Asm.html#Extended-Asm

Смотрел и др. сайты. Примеры одни и те же.

Попытался сделать это подобным образом
asm("pushl %0\n\tcall %1 \n\tpop %%eax" : : "r" (x1),"r"(printab));

Пишет предупреждение
indirect call without '*'
Но работает. Но что значит это предупреждение?
Как от него избавиться?
Я просто не понимаю, что имеется ввиду.
Что не есть гут.
Объясните пожалуйста, что это значит, и как от этого избавиться.
И (если они есть) другие способы вызова функций.
...
Рейтинг: 0 / 0
08.08.2005, 19:58
    #33206493
White Owl
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Ассемблерные вставки в c++. GNU
TnedutSПишет мне
undefined reference to printab

Ну так объяви саму функцию. Хотя бы через
void printtab(void);
в начале модуля а потом уже и ассемблерные вставки могут быть.
...
Рейтинг: 0 / 0
08.08.2005, 20:08
    #33206499
TnedutS
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Ассемблерные вставки в c++. GNU
Так я объявил же...

void printab(int );
...
int x1 = 1;
asm("pushl %0\n\tcall printab \n\tpop %%eax" : : "r" (x1));
...
void printab(int a)
{
...
}

Или что-то другое имеется ввиду?
...
Рейтинг: 0 / 0
08.08.2005, 20:13
    #33206502
NewYear
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Ассемблерные вставки в c++. GNU
ниче не понил. но все равно что-нибудь скажу.

может так

Код: plaintext
1.
extern "C" void printab(int );

или

Код: plaintext
1.
extern "что-нибудь" void printab(int );
...
Рейтинг: 0 / 0
08.08.2005, 20:16
    #33206503
NewYear
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Ассемблерные вставки в c++. GNU
ну это я просто видел в других OS подобную хрень...

типа extern "ASM", extern "OS", #pragma linkage( OS, ... ) ....
...
Рейтинг: 0 / 0
08.08.2005, 20:18
    #33206505
TnedutS
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Ассемблерные вставки в c++. GNU
NewYearниче не понил. но все равно что-нибудь скажу.

может так

Код: plaintext
1.
extern "C" void printab(int );

или

Код: plaintext
1.
extern "что-нибудь" void printab(int );


Как было, так и осталось...
"undefined reference"
...
Рейтинг: 0 / 0
08.08.2005, 20:21
    #33206507
TnedutS
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Ассемблерные вставки в c++. GNU
White Owl TnedutSПишет мне
undefined reference to printab

Ну так объяви саму функцию. Хотя бы через
void printtab(void);
в начале модуля а потом уже и ассемблерные вставки могут быть.

Я все функции, которые создаю в начале модуля объявляю. И эта тоже в объявлениях есть.
...
Рейтинг: 0 / 0
09.08.2005, 12:34
    #33206550
kolobok0
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Ассемблерные вставки в c++. GNU
TnedutSЯ все функции, которые создаю в начале модуля объявляю. И эта тоже в объявлениях есть.

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

с уважением
(круглый)
...
Рейтинг: 0 / 0
09.08.2005, 12:36
    #33206555
kolobok0
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Ассемблерные вставки в c++. GNU
И ещё одна мысля...
Сделайте для начала чиссо азмовскую метку. Попробуйте позвать её. Далее станет понятно - что хромает. Обьявление или что то ышо.

с уважением
(круглый)
...
Рейтинг: 0 / 0
09.08.2005, 13:05
    #33206647
TnedutS
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Ассемблерные вставки в c++. GNU
kolobok0 TnedutSЯ все функции, которые создаю в начале модуля объявляю. И эта тоже в объявлениях есть.

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

с уважением
(круглый)

Сделал ближе некуда. Не помогло.

void printab(int a)
{
printf("I'm writing %d\n",a);
}

int main(int argc, char* argv[])
{
*********************
/*debug section
*/
int x1=1;

asm("pushl %0\n\tcall printab\n\tpopl %%eax" : : "r" (x1)/*,"r" (printab)*/);
...
Рейтинг: 0 / 0
09.08.2005, 13:07
    #33206653
TnedutS
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Ассемблерные вставки в c++. GNU
kolobok0И ещё одна мысля...
Сделайте для начала чиссо азмовскую метку. Попробуйте позвать её. Далее станет понятно - что хромает. Обьявление или что то ышо.

с уважением
(круглый)

С метками сделал так.
...
void printab(int a)
{
printf("I'm writing %d\n",a);
}

int main(int argc, char* argv[])
{
*********************
/*debug section
*/
int x1=1;

asm("mark: pushl $0\n\t popl %eax\n\t");
asm("pushl %0\n\t call %1\n\tpopl %%eax\n\t jmp mark" : : "r" (x1),"r" (printab));
...

Замечательный вечный цикл получился.
...
Рейтинг: 0 / 0
09.08.2005, 13:17
    #33206691
TnedutS
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Ассемблерные вставки в c++. GNU
Похоже, придется ограничиться "кривым" способом. Хоть работает...
...
Рейтинг: 0 / 0
09.08.2005, 14:33
    #33206895
v6y
v6y
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Ассемблерные вставки в c++. GNU
TnedutSПривет всем.
Я вот тут пытаюсь ассемблерную вставку в с++ запихнуть...
А не получается. Точнее получается... Но как - то криво.

Пишу просто для пробы:
...
void printab(int );
int x1;
asm("pushl %0\n\tcall printab \n\tpop %%eax" : : "r" (x1));
...
Пишет мне
undefined reference to printab

Смотрел в инете. Нашел, например это:

asm ("movl %0,r9\n\tmovl %1,r10\n\tcall _foo"
: /* no outputs */
: "g" (from), "g" (to)
: "r9", "r10");

Но ведь тут тоже _foo неопределена.
Это отсюда:
http://gcc.activeventure.org/Extended-Asm.html#Extended-Asm

Смотрел и др. сайты. Примеры одни и те же.


Да все нормально работает. Немного код изменил, чтоб хоть какой то смысл придать:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
#include <stdio.h>
int x= 0 ;

#ifdef __cplusplus
 extern "C" void printab(int);
#endif

void printab(int x1) {
 if (++x< 20 )
  asm("pushl %0\n\tcall printab \n\tpop %%eax" : : "r" (x));
 printf("%u\n",x1);
}

main() {
 printab(x);
}



Попытался сделать это подобным образом
asm("pushl %0\n\tcall %1 \n\tpop %%eax" : : "r" (x1),"r"(printab));

Пишет предупреждение
indirect call without '*'
Но работает. Но что значит это предупреждение?
Как от него избавиться?
Я просто не понимаю, что имеется ввиду.
Что не есть гут.
Объясните пожалуйста, что это значит, и как от этого избавиться.
И (если они есть) другие способы вызова функций.
Если смотреть ассемблерный листинг, то в данном случае адрес printab помещается в eax (потому и не ругается на неизвестное имя ), затем происходит вызов call %eax, в первом же случае происходит вызов call printab напрямую
...
Рейтинг: 0 / 0
09.08.2005, 15:18
    #33207033
TnedutS
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Ассемблерные вставки в c++. GNU
#include <stdio.h>
int x=0;

#ifdef __cplusplus
extern "C" void printab(int);
#endif

void printab(int x1) {
if (++x<20)
asm("pushl %0\n\tcall printab \n\tpop %%eax" : : "r" (x));
printf("%u\n",x1);
}

int main(int argc, char* argv[])
{
///////////////////////////////////////////////////////////////////////////////////
//*********************************************************************************

printab(x);


Не работает....
Не понимаю.

Один в один скопировал - не пашет.
Может, в версии компилятора дело?

Кстати, на счет придания смысла.
Дело в том, что все делается ради того, чтобы сначала загнать в стек параметры, а потом вызвать какую-то постороннюю функцию.
Вот и тренируюсь на кошках.
А тут сама себя она вызывает как-то.
...
Рейтинг: 0 / 0
09.08.2005, 15:24
    #33207048
TnedutS
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Ассемблерные вставки в c++. GNU
У меня gcc 3.3.3
Может, в этом дело?
...
Рейтинг: 0 / 0
09.08.2005, 15:33
    #33207080
v6y
v6y
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Ассемблерные вставки в c++. GNU
TnedutS#include <stdio.h>
int x=0;

#ifdef __cplusplus
extern "C" void printab(int);
#endif

void printab(int x1) {
if (++x<20)
asm("pushl %0\n\tcall printab \n\tpop %%eax" : : "r" (x));
printf("%u\n",x1);
}

int main(int argc, char* argv[])
{
///////////////////////////////////////////////////////////////////////////////////
//*********************************************************************************

printab(x);


Не работает....
Не понимаю.

Один в один скопировал - не пашет.
Может, в версии компилятора дело?

Пробовал в Линуксе на 2.95.2 и 3.3.5 - нормально работало.

Операционка, имя файла, строка компиляции? Попробовать получить командой gcc -S имя_файл ассемблерный листинг и изучить его.

Кстати, на счет придания смысла.
Дело в том, что все делается ради того, чтобы сначала загнать в стек параметры, а потом вызвать какую-то постороннюю функцию.
Вот и тренируюсь на кошках.
А тут сама себя она вызывает как-то.
Да что она делает я понял, я не понял зачем тут бесконечная рекурсия (стек завалить чтоль) и передача мусора в качестве параметра.
...
Рейтинг: 0 / 0
09.08.2005, 16:18
    #33207252
TnedutS
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Ассемблерные вставки в c++. GNU
v6y TnedutS#include <stdio.h>
int x=0;

#ifdef __cplusplus
extern "C" void printab(int);
#endif

void printab(int x1) {
if (++x<20)
asm("pushl %0\n\tcall printab \n\tpop %%eax" : : "r" (x));
printf("%u\n",x1);
}

int main(int argc, char* argv[])
{
///////////////////////////////////////////////////////////////////////////////////
//*********************************************************************************

printab(x);


Не работает....
Не понимаю.

Один в один скопировал - не пашет.
Может, в версии компилятора дело?

Пробовал в Линуксе на 2.95.2 и 3.3.5 - нормально работало.

Операционка, имя файла, строка компиляции? Попробовать получить командой gcc -S имя_файл ассемблерный листинг и изучить его.


Кстати, на счет придания смысла.
Дело в том, что все делается ради того, чтобы сначала загнать в стек параметры, а потом вызвать какую-то постороннюю функцию.
Вот и тренируюсь на кошках.
А тут сама себя она вызывает как-то.
Да что она делает я понял, я не понял зачем тут бесконечная рекурсия (стек завалить чтоль) и передача мусора в качестве параметра.

Операционка WinXP проф.Version 2002 . Service Pack 2.
Я себе cygwin скачал.
Файл называется PartPC.cpp. Если это о компилируемом файле.
Ну там еще вдобавок
pseudoAPI.cpp и pseudoAPI.h - Это класс, который использую в PartPC.
Но сейчас этот класс не использую. Просто закомментировал все.
Строка компиляции...
Я использую eclipse cdt.
Там создается автоматический makefile.

################################################################################
# Automatically-generated file. Do not edit!
################################################################################

ROOT := ..

-include $(ROOT)/makefile.init

RM := rm -rf

# All of the sources participating in the build are defined here
-include sources.mk
-include $(SUBDIRS:%=%/subdir.mk)
-include objects.mk
-include $(DEPS)
-include $(ROOT)/makefile.defs

all: PartPC.exe

PartPC.exe: $(OBJS)
@echo 'Building target: $@'
g++ -o $@ $(OBJS) $(USER_OBJS) $(LIBS)
@echo 'Finished building: $@'

clean:
-$(RM) $(OBJS) $(DEPS) PartPC.exe

.PHONY: all clean dependents

-include $(ROOT)/makefile.targets

Так это выглядит.

А про gcc -s.
Не уверен, что мне это сейчас поможет.
У меня очень мало опыта с асмом. Да и вообще в общем, надо сказать.
Я даже не знаю, что именно мне надо в листинге искать. Можно подсказать, что надо искать?
Я могу попробовать, но боюсь,правда, тогда ничего не успею...
...
Рейтинг: 0 / 0
09.08.2005, 16:27
    #33207301
v6y
v6y
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Ассемблерные вставки в c++. GNU
Операционка WinXP проф.Version 2002 . Service Pack 2.
Я себе cygwin скачал.
Файл называется PartPC.cpp. Если это о компилируемом файле.
Ну там еще вдобавок
pseudoAPI.cpp и pseudoAPI.h - Это класс, который использую в PartPC.
Но сейчас этот класс не использую. Просто закомментировал все.
Строка компиляции...
Я использую eclipse cdt.
Там создается автоматический makefile.

################################################################################
# Automatically-generated file. Do not edit!
################################################################################

ROOT := ..

-include $(ROOT)/makefile.init

RM := rm -rf

# All of the sources participating in the build are defined here
-include sources.mk
-include $(SUBDIRS:%=%/subdir.mk)
-include objects.mk
-include $(DEPS)
-include $(ROOT)/makefile.defs

all: PartPC.exe

PartPC.exe: $(OBJS)
@echo 'Building target: $@'
g++ -o $@ $(OBJS) $(USER_OBJS) $(LIBS)
@echo 'Finished building: $@'

clean:
-$(RM) $(OBJS) $(DEPS) PartPC.exe

.PHONY: all clean dependents

-include $(ROOT)/makefile.targets

Так это выглядит.

А про gcc -s.
Не уверен, что мне это сейчас поможет.
У меня очень мало опыта с асмом. Да и вообще в общем, надо сказать.
Я даже не знаю, что именно мне надо в листинге искать. Можно подсказать, что надо искать?
Я могу попробовать, но боюсь,правда, тогда ничего не успею...

Ужис, предупреждать надо (это я про ОС и все остальное) Вобщем предлагаю попростому. Мой вариант закинуть в отдельний файл, скажем tst.c, потом попробовать gcc -o tst tst.c, затем g++ -o tst tst.c Если все нормально, то проблема явно не в gcc. В листинге можно увидеть какое имя на самом деле используется компилятором. Например printab(int) на самом деле будет что типа _Z7printabi, если компилить в стиле C++.
...
Рейтинг: 0 / 0
09.08.2005, 16:43
    #33207382
TnedutS
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Ассемблерные вставки в c++. GNU
v6yУжис, предупреждать надо (это я про ОС и все остальное) Вобщем предлагаю попростому. Мой вариант закинуть в отдельний файл, скажем tst.c, потом попробовать gcc -o tst tst.c, затем g++ -o tst tst.c Если все нормально, то проблема явно не в gcc. В листинге можно увидеть какое имя на самом деле используется компилятором. Например printab(int) на самом деле будет что типа _Z7printabi, если компилить в стиле C++.

Блин. Было у меня чувство "Пиши в MVS". Так нет... Блин..
Итак...
Это probe.c
#include <stdio.h>
int x=0;

#ifdef __cplusplus
extern "C" void printab(int);
#endif

void printab(int x1) {
if (++x<20)
asm("pushl %0\n\tcall printab \n\tpop %%eax" : : "r" (x));
printf("%u\n",x1);
}

int main(int argc, char* argv[])
{

printab(x);

}

Строка компиляции.
gcc - o probe probe.c

"undefined reference to printab"

При g++ - o probe probe.c
Та ж фигня
...
Рейтинг: 0 / 0
09.08.2005, 16:50
    #33207414
TnedutS
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Ассемблерные вставки в c++. GNU
Менять g++?
Или есть еще варианты?
Или во всем виноват Билл Гейтс?
...
Рейтинг: 0 / 0
09.08.2005, 18:36
    #33207737
TnedutS
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Ассемблерные вставки в c++. GNU
И, наконец, если кому интересно, решение!
Win добавляет функциям подчерки. Поэтому

после g++ -S probe.c (спасибо v6y :))

выглядело это так
...
_printab:
...
/APP
pushl %eax
call printab
pop %eax
...

Поэтому следовало сделать так:

#include <stdio.h>
int x=0;

#ifdef __cplusplus
extern "C" void printab(int);
#endif

void printab(int x1)
{
printf("%u\n",x1);
}

int main(int argc, char* argv[])
{

asm("pushl %0\n\tcall _printab \n\tpop %%eax" : : "r" (1));
//printab(x);
for(;;);

}

Спасибо всем!
И еще куче народу на других форумах:)
...
Рейтинг: 0 / 0
09.08.2005, 23:02
    #33207876
White Owl
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Ассемблерные вставки в c++. GNU
TnedutSИ, наконец, если кому интересно, решение!
Win добавляет функциям подчерки.
На самом деле это не Win. Это стандарт компиляторов С.
Это можно отключать специальным ключиком у компилятора или ключевымс словами. К сожалению ключевые слова разные у разных компиляторов. Большинство Windows-based компиляторов знают слово stdcall (или __stdcall).
GNU C использует слово asm: http://gcc.gnu.org/onlinedocs/gcc-4.0.1/gcc/Asm-Labels.html#Asm-Labels
...
Рейтинг: 0 / 0
10.08.2005, 10:54
    #33207962
v6y
v6y
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Ассемблерные вставки в c++. GNU
White Owl
На самом деле это не Win. Это стандарт компиляторов С.

Это точно стандарт? Ссылку можно? (Вопрос для меня непринципиальный, поэтому самому искать ответ лень) Может быть это не стандарт, а типа соглашения компиляторов под Вин? Потому как под Линуксом по умолчанию никаких подчеркиваний впереди не добавляется - или там стандарт нарушают?
...
Рейтинг: 0 / 0
10.08.2005, 11:25
    #33208070
TnedutS
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Ассемблерные вставки в c++. GNU
Ага.
Буду знать.
Спасибо
...
Рейтинг: 0 / 0
10.08.2005, 13:06
    #33208099
kolobok0
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Ассемблерные вставки в c++. GNU
v6y.... Может быть это не стандарт...

Более того, это зависит от того, кто чистит стэк. Вызывающий или вызываемый.


с уважением
(круглый)
...
Рейтинг: 0 / 0
Форумы / C++ [игнор отключен] [закрыт для гостей] / Ассемблерные вставки в c++. GNU / 25 сообщений из 35, страница 1 из 2
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]