С Новым годом! Форум программистов, компьютерный форум, киберфорум
Assembler: Linux
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.83/18: Рейтинг темы: голосов - 18, средняя оценка - 4.83
0 / 0 / 1
Регистрация: 29.10.2017
Сообщений: 114
1

При использовании процедур ошибка сегментации (связь си и асм)

31.03.2018, 20:35. Показов 3753. Ответов 29
Метки с, си (Все метки)

Author24 — интернет-сервис помощи студентам
В общем такая проблемка нужно передать мат. выражения с помощью процедур.
Написал модуль на Си вроде бы правильно, скомпилировал gcc -c main.c.
Написал модуль на ассемблере командой nasm -f elf32 asm.asm -o asm.obj.
Cкомпоновал модуль на Си и асм командой gcc -o start main.o a.obj -lm.
При запуске исполняемого файла start вылазит ошибка: "Ошибка сегментирования (core dumped)".
Пока новичок в этом деле, может где-то не так понял. Компиляция под Linux. Подскажите кто знает где эта ошибка?
Файл main.c:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <stdio.h>
#include <math.h>
 
extern __attribute__((cdecl)) int x(int _a, int _b, int _c)
{
    return (sin(_a-_b)*_c);
}
 
extern __attribute__((stdcall)) int y(int _a, int _b, int _c, int _d)
{
    return ((_a+_b)*_c-cos(_d));
}
 
extern __attribute__((fastcall)) int xy(int _a, int _b, int _c, int _d);
 
void main()
{
    int a=1;
    int b=2;
    int c=3;
    int d=4;
    printf("x:%d\ny:%d\nxy:%d\n",x(a,b,c),y(a,b,c,d),xy(a,b,c,d));
}
Файл asm.asm:
Assembler
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
global xy
extern x
extern y
 
section .text
 
    xy:
 
        ;fastcall
        push ebp
        mov ebp, esp
        mov ecx, [ebp+8]    ;a
        mov edx, [ebp+12]   ;b
        mov eax, [ebp+20]   ;d
        mov eax, [ebp+16]   ;c
        add esp, 8
        mov esp, ebp
 
        ;cdecl
        call x
        mov eax, [ebp+16]   ;c
        mov eax, [ebp+12]   ;b
        mov eax, [ebp+8]    ;a
 
        ;stdcall
        call y
        mov eax, [ebp+20]   ;d
        mov eax, [ebp+16]   ;c
        mov eax, [ebp+12]   ;b
        mov eax, [ebp+8]    ;a
        add esp, 16
        mov esp, ebp
        pop ebp
 
    ret
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
31.03.2018, 20:35
Ответы с готовыми решениями:

Проблема с кодировкой при использовании процедур
Здравствуйте. Возникла проблема с кодировкой при использовании процедур. Сама база в utf8 и там уже...

Ошибка сегментации при срабатывании деструктора
Всем привет. Помогите, пожалуйста, разобраться с деструкторами. Суть проблемы заключается вот в...

Ошибка сегментации при выводе графа
Вечер добрый, г-да программисты! Ниже приведены фрагменты из программы, описывающей и выводящей...

Ошибка сегментации при создании списка
Здрасти))) Вот такая небольшая проблема со списком)))) список читаем из файла и сортируем его))...

29
Модератор
Эксперт по электронике
8541 / 4393 / 1651
Регистрация: 01.02.2015
Сообщений: 13,649
Записей в блоге: 9
31.03.2018, 20:43 2
Теряюсь сказать, как в gcc применяется fastcall, но судя по описанию в Wikipedia
Соглашение о вызове
параметры передаются через регистры, а не через стек.

Может это причина?

Добавлено через 1 минуту
Ну и очистка стека должна производиться в вызываемой подпрограмме. А этого у вас нет.
Ошибся.
1
0 / 0 / 1
Регистрация: 29.10.2017
Сообщений: 114
31.03.2018, 20:43  [ТС] 3
Там первые два параметра через регистры, остальные через стек
0
Модератор
Эксперт по электронике
8541 / 4393 / 1651
Регистрация: 01.02.2015
Сообщений: 13,649
Записей в блоге: 9
31.03.2018, 20:46 4
Думаю, что вы неправильно их используете.
Кроме того, при вызове процедур x и y параметры помещаются в стек. А у вас этого нет.
0
0 / 0 / 1
Регистрация: 29.10.2017
Сообщений: 114
31.03.2018, 20:53  [ТС] 5
Посмотрите так правильно будет? Ошибка всё равно есть.
Делал по примерам что находил, там везде 2 параметра передаются, мб где-то неправильно понял.
Assembler
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
global xy
extern x
extern y
 
section .text
 
    xy:
 
        ;fastcall
        push ebp
        mov ebp, esp
        mov ecx, [ebp+8]    ;a
        mov edx, [ebp+12]   ;b
        mov eax, [ebp+20]   ;d
        push eax
        mov eax, [ebp+16]   ;c
        push eax
        add esp, 8
        mov esp, ebp
        pop ebp
 
        ;cdecl
        call x
        push ebp
        mov ebp, esp
        mov eax, [ebp+16]   ;c
        push eax
        mov eax, [ebp+12]   ;b
        push eax
        mov eax, [ebp+8]    ;a
        push eax
        pop ebp
 
        ;stdcall
        call y
        push ebp
        mov ebp, esp
        mov eax, [ebp+20]   ;d
        push eax
        mov eax, [ebp+16]   ;c
        push eax
        mov eax, [ebp+12]   ;b
        push eax
        mov eax, [ebp+8]    ;a
        push eax
        add esp, 16
        mov esp, ebp
        pop ebp
 
    ret
0
Модератор
Эксперт по электронике
8541 / 4393 / 1651
Регистрация: 01.02.2015
Сообщений: 13,649
Записей в блоге: 9
31.03.2018, 21:20 6
Думаю - нет.
Если fastcall, то параметры a и b передаются через регистры ecx и edx, но никак не через стек.
И функция x принимает 3 параметра.
Должно быть что-то такое
Assembler
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
xy:
  push ebp
  mov ebp, esp
 
  mov eax, [ebp+8] ;c
  push eax
  push edx ;b
  push ecx ;a
  call x
  sub esp, 12
 
  push eax ;значение x(a,b,c)
 
  push ecx ;a
  push edx ;b
  mov eax, [ebp+8] ;c
  push eax
  mov eax, [ebp+12] ;d
  push eax
  call y
 
  pop ebx
;в этом месте eax=y, ebx=x
1
0 / 0 / 1
Регистрация: 29.10.2017
Сообщений: 114
31.03.2018, 22:48  [ТС] 7
Всё равно такая же ошибка, буду ещё пробовать.

Добавлено через 1 час 21 минуту
Объясните кто-нибудь что не так или как нужно передавать параметры в ху, х и у?
0
Модератор
Эксперт по электронике
8541 / 4393 / 1651
Регистрация: 01.02.2015
Сообщений: 13,649
Записей в блоге: 9
01.04.2018, 10:02 8
Постарайтесь локализовать ошибку. Оформите вызовы процедур в разных строках и, выполняя по шагам, узнаете, которая из них вызывает ошибку.

Добавлено через 10 часов 25 минут
В программе на C функции x и y объявлены внешними, но реализация в C. Разве это правильно? Может быть не нужно для них extern использовать?
0
0 / 0 / 1
Регистрация: 29.10.2017
Сообщений: 114
01.04.2018, 13:18  [ТС] 9
Вроде бы так надо. Я по отдельности понял как процедуры писать, а вот вместе все пока что нет.
0
Модератор
Эксперт по электронике
8541 / 4393 / 1651
Регистрация: 01.02.2015
Сообщений: 13,649
Записей в блоге: 9
01.04.2018, 19:36 10
К сожалению, мои познания C слишком ничтожны. Я даже скомпилироватть не смог для проверки.
Набрал asm.asm, скомпилировал его, а с C скомпоновать не получилось
Assembler
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
global xy
extern x
extern y
 
section .text
 
    xy:
 
        ;fastcall
        push ebp
        mov ebp, esp
 
        ;cdecl
      push ecx
      push edx
 
      mov eax, [ebp+8] ;c
      push eax
      push edx ;b
      push ecx ;a
      call x
      sub esp, 12
      pop edx
      pop ecx
      push eax ;значение x(a,b,c)
 
        ;stdcall
      push ecx ;a
      push edx ;b
      mov eax, [ebp+8] ;c
      push eax
      mov eax, [ebp+12] ;d
      push eax
      call y
 
      pop ebx
      ;в этом месте eax=y, ebx=x
      add   eax, ebx
 
        mov esp, ebp
        pop ebp
 
    ret
0
0 / 0 / 1
Регистрация: 29.10.2017
Сообщений: 114
01.04.2018, 20:48  [ТС] 11
В общем почитал ещё и написал такое:
Assembler
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
global xy
extern x
extern y
 
section .text
 
    xy:
    ;fc
    push ebp
    mov ebp, esp
    mov ebx, [ebp+16]   ;c
    push ebx
    mov edx, [ebp+12]   ;b
    mov ecx, [ebp+8]    ;a
 
    call x
    ;cd
    add esp, 4
    push eax
    mov ebx, [ebp+20]
    push ebx
    mov ebx, [ebp+12]
    push ebx
    mov ebx, [ebp+8]
    push ebx
 
    call y
    ;sc
    pop ebx
    add eax, ebx
    pop ebp
    ret 16
Ошибка всё равно выскакивает. Где опять ошибся..
0
Модератор
Эксперт по электронике
8541 / 4393 / 1651
Регистрация: 01.02.2015
Сообщений: 13,649
Записей в блоге: 9
01.04.2018, 21:06 12
Alexis_777, ну вот скажите, в функцию xy параметр a попадает через ecx, параметр b через edx, а остальные через стек (ну вот так описано в Wikipedia - ссылку уже давал).
Значит через стек передаётся 2 параметра c и d.

Почему вы извлекаете параметры a и b из кадра стека?

Что я не понял в описании fastcall?

Добавлено через 1 минуту
Функция
x - cdecl
y - stdcall
xy - fastcall
1
0 / 0 / 1
Регистрация: 29.10.2017
Сообщений: 114
02.04.2018, 19:05  [ТС] 13
Не заметил сразу ваше сообщение. Да со стеком я пока не разобрался как тут правильно данные извлекать. Попробую ваш пример и сам ещё попытаюсь сделать. Отпишу как что получится.
0
0 / 0 / 1
Регистрация: 29.10.2017
Сообщений: 114
02.04.2018, 19:16  [ТС] 14
То что вы написали в предыдущем посте заработало вот результат:
Считает нормально в принципе, х=-2.52, у=9.65, вот почему ху=-2 только не пойму.
Если я правильно понял должна быть сумма х и у.
Изображения
 
0
Модератор
Эксперт по электронике
8541 / 4393 / 1651
Регистрация: 01.02.2015
Сообщений: 13,649
Записей в блоге: 9
02.04.2018, 23:57 15
Теряюсь. Возможно, что x и y такие при отдельном вызове, а при вызове из xy результаты иные, например, из-за ошибки порядка помещения в стек. Попробуйте объявить глобальные переменные, в которые поместите и распечатаете значения a, b, c, d, x, y из процедуры xy. Т.е. произвести отладочную печать.
Подозреваю, что порядок переменных в стеке отличается или адресация к параметрам в кадре стека ошибочна.
0
0 / 0 / 1
Регистрация: 29.10.2017
Сообщений: 114
03.04.2018, 00:50  [ТС] 16
Не знаю как их распечатать, но попробую выявить проблему
0
Модератор
Эксперт по электронике
8541 / 4393 / 1651
Регистрация: 01.02.2015
Сообщений: 13,649
Записей в блоге: 9
03.04.2018, 00:57 17
В asm.asm объявить внешние переменные. Сами переменные объявить в main.c. Из xy сохранить в эти переменные значения параметров. После вызова xy распечатать и эти переменные.
1
0 / 0 / 1
Регистрация: 29.10.2017
Сообщений: 114
03.04.2018, 00:59  [ТС] 18
При каждом запуске значения ху меняются. Попробую это сделать.
0
0 / 0 / 1
Регистрация: 29.10.2017
Сообщений: 114
05.04.2018, 01:29  [ТС] 19
Как не пытался переписать код всё равно ху рандомные значения выдаёт, а с х и у всё нормально
0
Модератор
Эксперт по электронике
8541 / 4393 / 1651
Регистрация: 01.02.2015
Сообщений: 13,649
Записей в блоге: 9
05.04.2018, 10:08 20
Alexis_777, у меня не получилось скомпилировать программу в сборе. Поэтому могу только предполагать.
Недавно тоже пробовал разобраться с передачей параметров через стек без макросов. Запутался с адресами параметров в кадре стека. Помогла пошаговая отладака в отладчике. Нашёл процедуру в куче кода (помечал её пачкой nop'ов для облегчения поиска), поставил точку останова, а потом осмотрел содержимое стека и смещения в нём. Увидел, что неправильно обращался к параметрам (mov eax, [ebp+16] - нужно было другое смещение).

Ещё, как вариант - сохранить в глобальных переменных несколько значений из кадра стека и распечатать их и оценить, что где находится, сравнить с эталонными передаваемыми параметрами. И по результатам сравнения разобраться со смещениями.

Ещё подозреваю несовпадение разрядности кода main и asm, может и ОС.
1
05.04.2018, 10:08
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
05.04.2018, 10:08
Помогаю со студенческими работами здесь

Ошибка сегментации при освобождении памяти
Вот в упор не понимаю, почему программа вылетает уже на завершающем этапе. Пожалуйста, посмотрите,...

При отладке выдается ошибка сегментации
Всем привет! :) У меня такая проблема: программа по численным методам (кусок кода -...

Ошибка сегментации при записи строки
Доброго времени суток уважаемые форумчане!Помогоите исправить ошибку. Начну с условия задания,...

Ошибка сегментации при работе со строками
Задача: Дан файл содержащий строки вещественных чисел. Вычислить минимум и максимум в каждой...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru