Поиск:

Ответ в темуСоздание новой темы Создание опроса
> некторые вопросы по gas, требую пояснения некоторые моменты 
:(
    Опции темы
gumbert
Дата 17.12.2007, 14:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 7
Регистрация: 17.12.2007
Где: Волгоград

Репутация: нет
Всего: нет



Значится так, возникла необходимость мне сделать несколько лабораторных по ассемблеру. 

1. Решить простой примерчик (c+4*d-123)/(1-a/2), но сделать ввод переменных в си, а реализацию решения самого примера на ассемблере. 

Как это увидел я. Основной файлик lab1.c на си, вызываем в нём функцию res.s на ассемблере. Компилирую командой 

Код

gcc lab1.c res.s


Компиляция проходит успешно, но при попытке ввести какие-либо данные, которые удовлетворяют ОДЗ (нпаример a=1 c=1 d=1) вылазит ошибка Floating point exception. В чем именно дело, понять не могу. На что стоит обратить внимание? Еще вопрос, если объявлять переменные a,c, и d не глобально, а в теле main, выдаются вот такие сообщения 
Код

/tmp/ccjrsxCS.o: In function `res':
(.text+0x7): undefined reference to `d'
/tmp/ccjrsxCS.o: In function `res':
(.text+0xc): undefined reference to `c'
/tmp/ccjrsxCS.o: In function `res':
(.text+0x14): undefined reference to `ch'
/tmp/ccjrsxCS.o: In function `res':
(.text+0x19): undefined reference to `a'
/tmp/ccjrsxCS.o: In function `res':
(.text+0x2d): undefined reference to `ch'
collect2: ld returned 1 exit status

так вот, как от этого избавиться? Т.е. как я понял, не передаются аргументы моей функции. Спасибо заранее.

Ещё мог напутать с синтаксисом в ассемблере, т.к. лекции у нас по intel ассемблеру.

lab1.c
Код

#include <stdio.h>

//int res(int a,int c,int d);

int a,c,d,y,ch;

int main(void)
{
        //int a,c,d;
        //int y;
        printf("(c+4*d-123)/(1-a/2)\n\n");
        printf("input a,c and d:\n");
        scanf("%d",&a);
        scanf("%d",&c);
        scanf("%d",&d);
        if(a/2!=1)
        {
            //y=(c+4*d-123)/(1-a/2);
            y=res(a,c,d);
            printf("res=%d\n",y);
        }
        else
            printf("znam=0\n");
        return 0;
}



res.s
Код

.globl res
res:
        movl $4,%eax
        imull $d,%eax
        addl $c,%eax
        subl $123,%eax
        movl $ch,%eax
        movl $a,%eax
        movl $2,%ecx
        idivl %ecx
        imull $-1,%eax
        addl $1,%eax
        movl %ecx,%eax
        movl $ch,%eax
        idivl %ecx
        ret




PM MAIL ICQ Jabber   Вверх
JackYF
Дата 17.12.2007, 15:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


полуавантюрист
****


Профиль
Группа: Участник
Сообщений: 5814
Регистрация: 28.8.2004
Где: страна тысячи озё р

Репутация: нет
Всего: 162



Цитата(gumbert @  17.12.2007,  14:45 Найти цитируемый пост)
вылазит ошибка Floating point exception.

У меня такое выдавалось недавно при делении на 0. Целых чисел smile Проверь, на всякий случай.


--------------------
Пожаловаться на меня как модератора можно здесь.
PM MAIL Jabber   Вверх
gumbert
Дата 17.12.2007, 15:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 7
Регистрация: 17.12.2007
Где: Волгоград

Репутация: нет
Всего: нет



Цитата(JackYF @  17.12.2007,  15:29 Найти цитируемый пост)
У меня такое выдавалось недавно при делении на 0. Целых чисел smile Проверь, на всякий случай. 

Так у меня в программе идёт проверка, если в знаменателе 0, то он до деления даже не дойдет.
PM MAIL ICQ Jabber   Вверх
MAKCim
Дата 17.12.2007, 17:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Воін дZэна
****


Профиль
Группа: Экс. модератор
Сообщений: 5644
Регистрация: 10.12.2005
Где: Менск, РБ

Репутация: 2
Всего: 207



gumbert
нда...
Цитата

y=res(a,c,d);

a, c, d в данном случае передаются через стек
код же функции res() его не использует для получения значений переданных переменных
Код

# res.S
.text
.globl res
res:
    movl    8(%esp), %eax # c
    movl    12(%esp), %edx # d
    movl    4(%esp), %ecx # a
    leal    -123(%eax, %edx, 2), %eax
    sarl    $1, %ecx
    decl    %ecx
    notl    %ecx
    xorl    %edx, %edx
    test    %eax, %eax
    setns    %dl
    decl    %edx
    idivl    %ecx
    ret


Добавлено через 3 минуты и 23 секунды
Цитата(gumbert @  17.12.2007,  14:45 Найти цитируемый пост)
Компиляция проходит успешно, но при попытке ввести какие-либо данные, которые удовлетворяют ОДЗ (нпаример a=1 c=1 d=1) вылазит ошибка Floating point exception. В чем именно дело, понять не могу

IDIV делит EDX:EAX на значение заданное регистровым (или адресным) операндом
при этом если EAX & 0x80000000 == true, то EDX должен быть равным 0xFFFFFFFF (-1)
иначе - нулю


--------------------
Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі ©

PM MAIL   Вверх
gumbert
Дата 17.12.2007, 21:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 7
Регистрация: 17.12.2007
Где: Волгоград

Репутация: нет
Всего: нет



Цитата(MAKCim @  17.12.2007,  17:19 Найти цитируемый пост)
gumbert, 
нда...

ну дык smile

MAKCim, так тоже не работает, таже самая ошибка...

PM MAIL ICQ Jabber   Вверх
MAKCim
Дата 17.12.2007, 22:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Воін дZэна
****


Профиль
Группа: Экс. модератор
Сообщений: 5644
Регистрация: 10.12.2005
Где: Менск, РБ

Репутация: 2
Всего: 207



Цитата(gumbert @  17.12.2007,  21:45 Найти цитируемый пост)
MAKCim, так тоже не работает, таже самая ошибка...

Код

#include <stdio.h>

extern int res(int, int, int);

int main() {
    int a = 1, c = 1, d = 1;
    printf("%d\n", res(a, c, d));
    return 0;
}

Код

.code32
.text
.globl res
res:
    movl    8(%esp), %eax # c
    movl    12(%esp), %edx # d
    movl    4(%esp), %ecx # a
    leal    -123(%eax, %edx, 4), %eax
    sarl    $1, %ecx
    decl    %ecx
    negl    %ecx
    xorl    %edx, %edx
    testl   %eax, %eax
    setns   %dl
    decl    %edx
    idivl   %ecx
    ret

все прекрасно работает
показывай полный код

Это сообщение отредактировал(а) MAKCim - 17.12.2007, 22:09


--------------------
Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі ©

PM MAIL   Вверх
gumbert
Дата 17.12.2007, 23:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 7
Регистрация: 17.12.2007
Где: Волгоград

Репутация: нет
Всего: нет



MAKCim, вот теперь работает, спасибо! У меня это выглядит теперь вот так. 

Код

#include <stdio.h>

extern int res(int a,int c,int d);

int main()
{
        int a,c,d;
        printf("(c+4*d-123)/(1-a/2)\n\n");
        printf("input a,c and d:\n");
        scanf("%d",&a);
        scanf("%d",&c);
        scanf("%d",&d);
        if(a/2!=1)
                printf("res=%d\n",res(a,c,d));
        else
            printf("znam=0\n");
        return 0;
}


Код

.text
.globl res
res:
    movl    8(%esp), %eax # c
    movl    12(%esp), %edx # d
    movl    4(%esp), %ecx # a
    leal    -123(%eax, %edx, 4), %eax
    sarl    $1, %ecx
    decl    %ecx
    negl    %ecx
    xorl    %edx, %edx
    testl    %eax, %eax
    setns   %dl
    decl    %edx
    idivl   %ecx
    ret


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

PM MAIL ICQ Jabber   Вверх
MAKCim
Дата 17.12.2007, 23:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Воін дZэна
****


Профиль
Группа: Экс. модератор
Сообщений: 5644
Регистрация: 10.12.2005
Где: Менск, РБ

Репутация: 2
Всего: 207



Цитата(gumbert @  17.12.2007,  23:33 Найти цитируемый пост)
Кстати, обязательно прототип функции объявлять? И без него работает вроде. 

желательно


--------------------
Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі ©

PM MAIL   Вверх
gumbert
Дата 25.12.2007, 13:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 7
Регистрация: 17.12.2007
Где: Волгоград

Репутация: нет
Всего: нет



Ещё одна задачка. 

Вычислить выражение (c+4*d-sqr(123*c))/(1-a/2) используя арифметические операции сопроцессора. Причём a и b должны быть int, а c и d float (или double). 

У меня все переменные double. Как всё таки сделать те что надо int, а те что надо double? Как в данном случае работать со стеком? А то я опять через глобальное объявление переменных пошел... Ещё и в добавок считает неправильно. При a=1, c=1 и d=1 результат должен быть -12,1810730128, а у меня получается -0,200000. 

Ещё вопрос: в случае арифметического сопроцессора синтаксис тоже наоборот относительно интеловского?

Заранее спасибо.

Код

//lab4
#include <stdio.h>
#include <math.h>

double a, c, d;
double ott=123., f=4., t=-2.;

extern double res(double, double, double);

int main(void)
{
        //double a,c,d;
        //double ott=123., f=4., t=-2.;
        printf("input a, c and d\n");
        scanf("%lf %lf %lf",&a,&c,&d);
        if(a/2!=1)
                printf("res=%lf\n",res(a,c,d));
        else
                printf("znam=0\n");
        return 0;
}
 

Код

#res.s in lab4
.globl res
res:
        fldl    ott
        fmull   c
        fsqrt
        fldl    f
        fmull   d
        faddl   c
        fsub    %st(0), %st(1) 
        fldl    a
        fldl    t
        fdiv    %st(1), %st(0)
        fld1
        fadd    %st(1)
        fdiv    %st(3), %st(0)
        ret




PM MAIL ICQ Jabber   Вверх
MAKCim
Дата 25.12.2007, 14:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Воін дZэна
****


Профиль
Группа: Экс. модератор
Сообщений: 5644
Регистрация: 10.12.2005
Где: Менск, РБ

Репутация: 2
Всего: 207



Цитата(gumbert @  25.12.2007,  13:14 Найти цитируемый пост)
Ещё и в добавок считает неправильно. При a=1, c=1 и d=1 результат должен быть -12,1810730128

нет
результат ~ -6.09
т. к
(c + 4 * d - sqrt(123 * c)) / (1 - a / 2) = (1 + 4 - sqrt(123)) / (1 - 0)
т. к a - это int, то a / 2 = 0, если a = 1



--------------------
Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі ©

PM MAIL   Вверх
gumbert
Дата 25.12.2007, 14:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 7
Регистрация: 17.12.2007
Где: Волгоград

Репутация: нет
Всего: нет



Цитата(MAKCim @  25.12.2007,  14:12 Найти цитируемый пост)
нет
результат ~ -6.09
т. к
(c + 4 * d - sqrt(123 * c)) / (1 - a / 2) = (1 + 4 - sqrt(123)) / (1 - 0)
т. к a - это int, то a / 2 = 0, если a = 1

а, ну да. 
PM MAIL ICQ Jabber   Вверх
gumbert
Дата 25.12.2007, 16:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 7
Регистрация: 17.12.2007
Где: Волгоград

Репутация: нет
Всего: нет



делаю a int вообще nan получается...

попытаюсь воспроизвести ход моих рассуждений:
Код

#res.s in lab4
.globl res
res:
        fldl    ott #кладём ott=123. в st(0)
        fmull   c #умножаем st(0) на с=1., результат в st(0)
        fsqrt #извлекаем корень из st(0), результат обратно в st(0)
        fldl    f #кладём f=4. в st(0), корень из st(0) перемещается в st(1)
        fmull   d #умножаем st(0) на d=1., результат в st(0)
        faddl   c #прибавляем к st(0) с=1., результат в st(0)
        fsubr    #вычитаем из st(1) st(0), результат в st(0). получаем числитель
        fldl    a #кладём a=1 в st(0), числитель перемещается в st(1), корень в st(2)
        fldl    t #кладём t=-2. в st(0), все остальные регистры смещаются на 1 вправо
        fdiv     #делим st(1)=a на st(0)=-2., результат в st(0)
        fld1 #клвдём 1 в st(0), регистры опять на 1 смещаются вправо, т.е. числитель теперь в st(3)
        fadd   # st(0)+st(1), результат в st(0). получили знаменатель 
        fdiv    %st(0), %st(3) #делим st(3)(числитель) на st(0) (знаменатель), результат в st(3)
        fxch    %st(3) #меняет местами st(0) и st(3)
        ret  #возвращаем st(0)



подскажите, пожалуйста, где я не прав?
PM MAIL ICQ Jabber   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Asm для Linux/Unix"
MAKCim
  • Проставьте несколько ключевых слов темы, чтобы её можно было легче найти.
  • Не забывайте пользоваться кнопкой КОД.
  • Телепатов на форуме нет! Задавайте чёткий, конкретный и полный вопрос. Указывайте полностью ошибки компилятора и компоновщика.
  • Новое сообщение должно иметь прямое отношение к разделу форума. Флуд, флейм, оффтопик запрещены.
  • Категорически запрещается обсуждение вареза, "кряков", взлома программ и т.д.

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, MAKCim.

 
 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Asm для Linux/Unix | Следующая тема »


 




[ Время генерации скрипта: 0.1799 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.