Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Для новичков > функции Ассемблера, в программе на языке C


Автор: rujmaster 13.12.2009, 22:42
Есть функция, написанная на Ассемблере, требуется добавить ее в проект, написанный на языке С. Среда разработки MV C++ 6.0  
Функция на ассемблере:
Код

_BSS SEGMENT WORD PUBLIC 'DATA'

_BSS    ends

_TEXT   SEGMENT WORD PUBLIC 'CODE'
        ASSUME  cs: _TEXT, ds:_BSS
        PUBLIC   _power2
_power2 PROC
        push    bp     ;Входная последовательность-сохранения регис-
                        ;тра BP.
        mov     bp,sp  ;Установка записи активации.

        mov     ax,[bp+4]  ;Загрузка Arg1 в AX.
        mov     cx,[bp+6]  ;Загрузка Arg2 в CX.
        shl     ax,cl      ;AX = AX+(2 в степени CX).
                           ;Значение возврата остается в AX.
        pop     bp   ;Выходная последовательность-восстановление ре-
                     ; гистра BP.
        ret          ;Выход.
_power2 ENDP
_TEXT   ENDS
       END

код на С:

Код

//main.c
#include <stdio.h>
#include "module.h"

int main () {

    int a,b;

    scanf ("%d %d", &a, &b);

    power2 (a,b);

    return 0;
}

//module.h

#ifndef MODULE_H
#define MODULE_H

extern int    power2(int a, int b);


#endif


В-общем, как не пытался, компоновать не хочет. Куда нужно добавлять фаил obj? 

Автор: 586 13.12.2009, 23:01
Цитата(rujmaster @  13.12.2009,  22:42 Найти цитируемый пост)
Среда разработки MV C++ 6.0  

Visual C++ 6.0? Он же 32-битные exe-шники компилирует. Твой ассемблер не подойдёт. Нужен masm32.

Автор: rujmaster 13.12.2009, 23:07
Хорошо, допустим не MV6. Какую среду разработки выбрать? На ассемблере нужен именно tasm.
Cтавил Borland C++ 5.5, так он вообще ничего скомпилировать не может. Не находит библиотек.
А если изменить код asm на 32 разр?


Автор: smoke_man 13.12.2009, 23:20
Посмотри пример http://forum.sources.ru/index.php?showtopic=258759, а если tasm нужен, то для 32 разр используй tasm32.

Автор: bsa 13.12.2009, 23:27
rujmaster, если эта ассемблерная функция делает только то, что написал ты, то проще написать на си: b + (a << 1)

Автор: rujmaster 13.12.2009, 23:31
Ну в-общем то эта функция была взята в качестве примера. Реально же мне нужно создать функции для работы со строками, и я не могу отступать от требований лабораторной работы smile 

Автор: EvilsInterrupt 13.12.2009, 23:41
rujmaster, 
Слова про лабораторную работу, должен был сказать в первом посту! А тут множество людей, сразу не понимают, что человеку надо так и начинают давать кучу не нужных советов! ;)

А по делу!
Напиши тоже самое на fasm , синтаксис простой! Закомпиль в ввиде coff , ф-ции по cdecl декларации! Создай прототип на сях и обжуху закинь в проект в MS Visual Studio как обычный проект.
Не было требования по выбору ассемблера, потому предлагаю именно ФАСМ !!! Потому что разивается, а в мире ПО это чуть ли не важное свойство! Синтаксис тасмо-подобный! Имеет туеву хучу форматов и есть реализации под разными платформами! Это если ты будешь преподу говорить, надумав взять фасм ;)


ЗЫ:
Попробую с утра набросать, если работа не засосет )

Автор: rujmaster 14.12.2009, 00:01
Всем спасибо за советы, надеюсь дело сдвинется с мёртвой точки smile

Автор: rujmaster 14.12.2009, 21:44
Скачал borland C 3.1 , решил все таки использовать 16разр. В качестве примера взял следующую функцию:
Код


_BSS SEGMENT WORD PUBLIC 'DATA' 

_BSS    ends
 
_TEXT   SEGMENT WORD PUBLIC 'CODE'
        ASSUME  cs: _TEXT, ds:_BSS
        PUBLIC   _func1
_func1 PROC
     push    bp     ;пролог 
    ;push    si
    push    dx           
    mov     bp,sp  ;
    mov     ax,[bp+4]  ;
    mov    dx,[bp+6]

    add    ax,dx    

     pop    dx  
     pop     bp   ;эпилог           
     ret          ;Выход.
_func1 ENDP
_TEXT   ENDS
       END


Модуль на С:
Код


#include "stdio.h"
extern  int  func1 (int,int);


int main () {
    int a,b, z;
    scanf ("%d", &a);
    scanf ("%d", &b);
    z=func1 (a,b);
    printf ("%d\n", z);

    return 0;
}



Вроде компонуется и даже что-то считает  smile , хоть и неверно.
К примеру, если на вход записать a=1, b=1, то результат выводится = 748.
В чем ошибка?
Думаю, тему уже нужно в другой раздел smile

Автор: smoke_man 14.12.2009, 23:29
Посмотри http://www.citforum.ru/programming/tasm3/tasm3_18.shtml
Попробуй int a,b,z - поменять на short int

Добавлено через 1 минуту и 27 секунд
И тоже самое с прототипом функции funcl - int поменять на short int.

Автор: bsa 15.12.2009, 11:47
rujmaster, у Borland C++ есть возможность компиляции в ассемблерный текст. Напиши на С++ функцию, которая принимает то же количество аргументов, затем сделай ассемблерный текст и посмотри, как "достаются" переменные из стека.

Автор: xvr 15.12.2009, 11:54
Во первых -    mov     bp,sp надо ставить СРАЗУ ПОСЛЕ push bp
Во вторых - константы в mov     ?x,[bp+4] будут зависеть от модели памяти.
Советую написать функцию на С, потом откомпилировать ее в ассемблер и посмотреть на константы и на пролог/эпилог функции.

Автор: rujmaster 15.12.2009, 13:36
Спасибо, вопросов больше нет smile

Автор: rujmaster 15.12.2009, 15:16
А вообще-то есть )). Вот функция подсчета длины строки на asm:
Код

.MODEL SMALL

_BSS SEGMENT WORD PUBLIC 'DATA' 

_BSS    ends
 
_TEXT   SEGMENT WORD PUBLIC 'CODE'
        ASSUME  cs: _TEXT, ds:_BSS
PUBLIC   _func1
_func1 PROC NEAR
    ;arg    a:byte;
        push    bp     ;пролог        
        mov     bp,sp  ;
    xor    ax,ax
    xor    dx,dx
    jmp    m0
m1:    inc    dx
m0:
    mov    bx, word ptr [bp+4]
    add    bx,dx
    cmp    byte ptr [bx],0
    jne    m1
    mov    ax,dx
            pop     bp   ;эпилог           
            ret          
_func1 ENDP
_TEXT ENDS
END

Не понятна строчка :
Код

cmp    byte ptr [bx],0

почему bx в скобках?, и почему здесь необходимо делать преобразование?

Автор: xvr 15.12.2009, 15:24
Цитата(rujmaster @ 15.12.2009,  15:16)
Не понятна строчка :
Код

cmp    byte ptr [bx],0

почему bx в скобках?, 

В скобках потому что это косвенная адресация - из памяти читается байт по адресу содержащемуся в bx и ставнивается с 0

Цитата

и почему здесь необходимо делать преобразование?
Потому что иначе невозможно сказать какого размера надо делать чтение (и сравнение). Из мнемоники не ясно - байт/слово/двойное слово

Автор: rujmaster 15.12.2009, 20:14
С этим разобрался, спасибо!smile
C последнем заданием теперь проблемы. Функция должна найти заданный символ в строке, в случае его нахождения, возвратить указатель на него. Если же указанный символ не наиден, то функция должна возвратить нулевой указатель. Как я понял на asm в ax кидаем 0.
В рез-те у меня в случае, если символ наиден, выводится этот символ и все остальные символы, следующие за ним. Проблема в функции? или может вывод неверный
Ф-ия на asm
Код

.MODEL SMALL
_BSS SEGMENT WORD PUBLIC 'DATA' 

_BSS    ends
 
_TEXT   SEGMENT WORD PUBLIC 'CODE'
        ASSUME  cs: _TEXT, ds:_BSS



PUBLIC   _func3
_func3 PROC NEAR
    ;arg    a:byte;
        push    bp     ;пролог        
        mov     bp,sp  ;

    xor    cx,cx
    xor    ax,ax
    xor    dx,dx
    xor    si,si
    

    mov    cx,word ptr [bp+4]  ;cx- указатель на строчку

m1:    mov    bx,cx
    add    bx,dx
    cmp    byte ptr [bx],0
    je    nll
    
    mov    al,byte ptr [bx]
    cmp    al,byte ptr [bp+6]
    je    done
    inc    dx
    jmp    m1

nll:    xor    ax,ax
    
m0:     pop     bp   ;эпилог           
        ret          ;Выход.

done:    mov    ax,cx
    add    ax,dx
    
    jmp    m0
    
_func3 ENDP
_TEXT ENDS
END


вызывающая ф-ия:
Код

nclude "stdio.h"

extern char* func3 (char*,char);



int main () {
    char buf[100];
    //int z;

    scanf ("%s", buf);
    
    printf ("%s\n",func3(buf,'a'));


    return 0;
}



Автор: smoke_man 15.12.2009, 20:33
printf ("%s\n",func3(buf,'a')); - будет выводить значения пока не встретит окончание строки - '\0'. Можно сделать так:  как только нашел нужный символ  - следуюший за ним заменить символом конца строки.

Автор: xvr 15.12.2009, 22:03
Вот это     xor    si,si из asm функции надо убрать. Никакие asm функции не должны менять регистры si и di - они используются С функциями для хранения локальных переменных

PS. Asm функция - просто караул  smile 

Автор: rujmaster 15.12.2009, 23:44
 smile Главное, работает smile 

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