Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Программирование под Unix/Linux > вставка на asm'e


Автор: cupper 24.4.2010, 11:56
нужно сделать свой системный вызов, в качестве одного из параметров передается указатель на функцию

вот код функции делающей системный вызов
Код

static inline struct proc_dir_entry *func(const char *name,
    mode_t mode, struct proc_dir_entry *base, 
    read_proc_t *read_proc, void * data)
{
    
#define __STR(X) #X
#define STR(X) __STR(X)

    unsigned long ret;
        
    __asm__ __volatile__ (
        "\tmovl %1, %%ebx\n"
        "\tmovl %2, %%ecx\n"
        "\tmovl %3, %%edx\n"
        "\tmovl %4, %%esi\n"
        "\tmovl %5, %%edi\n"
        "\tmovl $"STR(__SR_numder)", %%eax\n"
        "\tint $0x80\n"
        "\tmovl %%eax, %0"
        :"=r" (ret):"r"(name), "r"(mode), "r"(base), "r"(read_proc), "r"(data) :"ebx","ecx","edx","esi","edi", "eax");

#undef STR
#undef __STR

    return ret;
}

при компиляции получаю
Код

include/linux/proc_fs.h:190: error: can't find a register in class 'GENERAL_REGS' while reloading 'asm'
include/linux/proc_fs.h:190: error: 'asm' operand has impossible constraints

190 строчка это __asm__ __volatile__ (

тип read_proc_t определен так
Код

typedef    int (read_proc_t)(char *page, char **start, off_t off,
              int count, int *eof, void *data);

Я не могу понять чего мне сообщает компилятор. Предполагаю что проблема как раз именно в этом параметре ибо остальные ничего особенного из себя не представляют.
Возможно к проблеме имеет отношения ранее возникшая и скорее всего неправильно решенная проблема с объявлением этой функции в другом файле. Эта проблема описана тут
http://forum.vingrad.ru/forum/topic-298481.html

Автор: MAKCim 24.4.2010, 13:48
cupper, 
вы попробуйте постепенно уменьшать число параметров и одновременно смотреть, исчезает ли проблема

Автор: cupper 24.4.2010, 18:28
Цитата(MAKCim @ 24.4.2010,  13:48)
cupper, 
вы попробуйте постепенно уменьшать число параметров и одновременно смотреть, исчезает ли проблема

попробовал убрать передачу функции, результат тот же. Щас все параметры убрал оставил только вызов int 0x80 и загрузку результата в регистр eax. 

Осложняется все тем что до момента ошибки компиляция доходит минут за 25 :(

Автор: cupper 24.4.2010, 19:36
судя по прошедвешу времени компиляции ошибка миновала, щас блин придеться всетаки поочереди все отключать параметры :(

PS. балин :( я когда убирал передачу указателя на функцию забыл изменить порядок регистров, это имеет значение ?
обязательно чтобы параметры передавались через регистры именно в таком порядке ebx, ecx, edx, esi, edi ? или регистры можно в любом порядке загружать ?

Автор: MAKCim 25.4.2010, 09:32
cupper, 
обязательно

Добавлено через 1 минуту и 2 секунды
Цитата(cupper @  24.4.2010,  18:28 Найти цитируемый пост)
Осложняется все тем что до момента ошибки компиляция доходит минут за 25 :( 

 smile 
а что мешает скомпилироать только этот файл?

Автор: cupper 25.4.2010, 16:56
Цитата(MAKCim @ 25.4.2010,  09:32)
а что мешает скомпилироать только этот файл?

мое незнание как это сделать  smile 
я как то ядро умею компилявить только глобально с помощью make

Автор: cupper 26.4.2010, 22:24
бейте меня ногами но предложенный способ мне не посилам. 
уже хренову кучу времени убил, а только проверил что без 
Код

mode_t mode
read_proc_t *read_proc

вылазает ошибка, а если убрать все и оставить только вызов int 0x80 то ошибки нет. Два остальных праметра вообще ничем не примечательно, остаеться только что либо эти оба параметра плохие, либо каким то непонятным образом эти совсем обычный параметры ему ненравяться :( 
Код

const char *name,
struct proc_dir_entry *base, 
void * data

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

Автор: MAKCim 27.4.2010, 09:18
уберите eax из clobbered-list'а

Автор: cupper 27.4.2010, 20:53
Цитата(MAKCim @ 27.4.2010,  09:18)
уберите eax из clobbered-list'а

доктор, а как поможет ампутация руки при спиде ?)

PS. ампутация не помогла, слава богу осталась правая  smile 
Хорошо что мы не врачи ))

Автор: MAKCim 27.4.2010, 22:32
Цитата(cupper @  27.4.2010,  20:53 Найти цитируемый пост)
доктор, а как поможет ампутация руки при спиде ?)

http://gcc.gnu.org/ml/gcc-help/2007-04/msg00200.html
судя по всему clobbered ist вообще должен быть пуст в данном случае

Автор: cupper 28.4.2010, 17:29
Цитата(MAKCim @ 27.4.2010,  22:32)
Цитата(cupper @  27.4.2010,  20:53 Найти цитируемый пост)
доктор, а как поможет ампутация руки при спиде ?)

http://gcc.gnu.org/ml/gcc-help/2007-04/msg00200.html
судя по всему clobbered ist вообще должен быть пуст в данном случае

в силу слабого знания инглиша я не понял чего там было в переписке сказанно. Я попробую и так сделать. 
Ме сказала что проблема так же может возникать при попытке положить в регистр 16ричного числа если переменная передаваемая в asm будет с меткой "r". Вопрос smile я понял что =r означает output параметр, r означает input, но какие получается они еще могут быть ?) 

PS.
Код

__asm__ __volatile__ (
        "\tmovl %1, %%ebx\n"
        "\tmovl %2, %%ecx\n"
        "\tmovl %3, %%edx\n"
        "\tmovl %4, %%esi\n"
        "\tmovl %5, %%edi\n"
        "\tmovl $"STR(__SR_func)", %%eax\n"
        "\tint $0x80\n"
        "\tmovl %%eax, %0"
        :"=r" (ret):"r"(name), "r"(mode), "r"(base), "r"(read_proc), "r"(data) :/*"ebx","ecx","edx","esi","edi", "eax"*/);

так сразу ошибка
Код

error: expected string literal before ')' token

судя по приведенной ссылке совсем не правильно понял что такое клобберед лист, там чета вообще непонятное происходит :(

Автор: MAKCim 28.4.2010, 22:45
cupper, 
последнее : не нужно

Автор: cupper 29.4.2010, 19:12
Цитата(MAKCim @ 28.4.2010,  22:45)
cupper, 
последнее : не нужно

спасибо
В итоге вот такой вариант скомпилировался
Код

__asm__ __volatile__ (
        "\tmovl %1, %%ebx\n"
        "\tmovw %2, %%ecx\n"
        "\tmovl %3, %%edx\n"
        "\tmovl %4, %%esi\n"
        "\tmovl %5, %%edi\n"
        "\tmovl $"STR(__SR_func)", %%eax\n"
        "\tint $0x80\n"
        "\tmovl %%eax, %0"
        :"=r" (ret):"r"(name), "g"(mode), "r"(base), "r"(read_proc), "r"(data) /*:"ebx","ecx","edx","esi","edi", "eax"*/);

теперь надо еще проверить работает ли он.
Еще щас попробую назад пернуть r вместо g и mowl.
И кстати а чем данный варинт кода особенен что нужно без клобберед листа ?

Автор: MAKCim 29.4.2010, 23:02
Цитата(cupper @  29.4.2010,  19:12 Найти цитируемый пост)
И кстати а чем данный варинт кода особенен что нужно без клобберед листа ?

юзаются все регистры общего назначения за исключением ebp/esp
компилятор не сможет их юзать для чего-то еще

и вообще, лучше так
Код

__asm__ __volatile__ (
        "\tmovl %1, %%ebx\n"
        "\tmovw %2, %%ecx\n"
        "\tmovl %3, %%edx\n"
        "\tmovl %4, %%esi\n"
        "\tmovl %5, %%edi\n"
        "\tmovl $"STR(__SR_func)", %%eax\n"
        "\tint $0x80\n"
        "\tmovl %%eax, %0"
        :"=m" (ret):"m"(name), "m"(mode), "m"(base), "m"(read_proc), "m"(data) :"ebx","ecx","edx","esi","edi", "eax");

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)