LinuxForum.Fans
Тема

[ASM] Зависает программа при вызове подпрограммы

Автор: Osanve 7 сообщений 1562 просмотров
#208315

Здравствуйте.

Никак не могу разобраться в чем проблема. Компилирую проект. Запускаю бинарник. Первый раз нажимаю на кнопку - все нормально, но потом программа зависает. Может быть взгляд со стороны подскажет в чем проблема?

Исходники:

Показать
Программа зависает после выполнения следующего кода:
text
.data
  file_name:
    .string "/dev/vcsa2"
  attrib1:
    .byte 0x74
  whiteSpace:
    .byte ' ', 0x70
  array:
    .byte 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
  array_end:

.text .globl generate .type generate, @function generate: pushq %rbp movq %rsp, %rbp /* Инициализируем генератор псевдослучайных чисел */ xorq %rdi, %rdi xorq %rax, %rax call time movq %rax, %rdi call srand /* Заполняем массив псевдослучайными числами */ movq $array, %rbx generate_loop: call rand xorq %rdx, %rdx movq $10, %rcx divq %rcx movb %dl, (%rbx) addq $1, %rbx cmpq $array_end, %rbx jne generate_loop /* Открываем файл для записи в видеопамять */ movq $file_name, %rdi movq $2, %rsi xorq %rax, %rax call open movq %rax, %rdi /* Встаем на нужную позицию видеопамяти */ movq $264, %rsi xorq %rdx, %rdx call lseek /* Записываем массив в видеопамять */ movq $array, %rbx print_loop: movb (%rbx), %al addb $48, %al movb %al, (%rbx) xorq %rsi, %rsi movq $1, %rdx call lseek movq %rbx, %rsi movq $1, %rdx call write movq $attrib1, %rsi call write xorq %rsi, %rsi movq $1, %rdx call lseek movq $whiteSpace, %rsi movq $1, %rdx call write movq $attrib1, %rsi call write incq %rbx cmpq $array_end, %rbx jne print_loop /* Выходим из подпрограммы */ movq %rbp, %rsp popq %rbp ret

Сам код вызывается отсюда:

text
#include <stdio.h>
#include <stdlib.h>
#include <gpm.h>

int my_handler(Gpm_Event *event, void *data) { if((event->y == 35) && ((event->x >= 48) && (event->x <= 51))) { exit(0); } if((event->y == 35) && ((event->x >= 20) && (event->x <= 27))) { (void)generate(); } return 0; }

int main() { Gpm_Connect conn; int c; conn.eventMask = GPM_DOWN; conn.defaultMask = ~conn.eventMask; conn.minMod = 0; conn.maxMod = ~0; (void)graph(); Gpm_Open(&conn, 0); gpm_handler = my_handler; while((c = Gpm_Getc(stdin)) != EOF) {} Gpm_Close(); return 0; }

#208328

ни чё не понял oO , где связь первого куска со вторым ? , чё за функции (void)generate(); и (void)graph(); , как ваще это работаетдолжно работать по задумке ? oO

#208339
gramozeka написал:
чё за функции (void)generate(); и (void)graph();

Функция generate() представлена в коде. Функция graph() реализована в другом ассемблерном модуле (работает нормально, поэтому код не приводил).

gramozeka написал:
где связь первого куска со вторым ?

[console]gcc ./mouse.c ./generate.s ./graph.s -lgpm[/console]
Так у меня всегда все нормально работало

gramozeka написал:
как ваще это работаетдолжно работать по задумке ?

Задание лабораторной все то же.
Вывод текста и фона реализовать записью в видеопамять. Реализовать поддержку мыши. При нажатии на одну кнопку в интерфейсе программы - сформировать новый массив псевдослучайных чисел и вывести его, на вторую - обработать массив и вывести результат, на третью - выйти из программы.

Собственно ничего сложного. Проблемка возникла только в этом.

#208355
Osanve написал:
Первый раз нажимаю на кнопку - все нормально, но потом программа зависает.

+

Osanve написал:
При нажатии на одну кнопку в интерфейсе программы - сформировать новый массив псевдослучайных чисел и вывести его,
text

.code  
start: 
mov edx,0   ; очистка регистров 
mov ebx,0   ; очистка регистров 
mov ecx,0 

чё за синтаксис такой ?

text

~/asm$ gcc ./mouse.c ./generate.s -lgpm
./generate.s: Assembler messages:
./generate.s:16: Error: bad register name `%rbp'
./generate.s:17: Error: bad register name `%rsp'
./generate.s:19: Error: bad register name `%rdi'
./generate.s:20: Error: bad register name `%rax'
./generate.s:22: Error: bad register name `%rax'
./generate.s:25: Error: bad register name `%rbx'
./generate.s:28: Error: bad register name `%rdx'
./generate.s:29: Error: bad register name `%rcx'
./generate.s:30: Error: bad register name `%rcx'
./generate.s:31: Error: bad register name `%rbx)'
./generate.s:32: Error: bad register name `%rbx'
./generate.s:33: Error: bad register name `%rbx'
./generate.s:36: Error: bad register name `%rdi'
./generate.s:37: Error: bad register name `%rsi'
./generate.s:38: Error: bad register name `%rax'
./generate.s:40: Error: bad register name `%rax'
./generate.s:42: Error: bad register name `%rsi'
./generate.s:43: Error: bad register name `%rdx'
./generate.s:46: Error: bad register name `%rbx'
./generate.s:48: Error: bad register name `%rbx)'
./generate.s:50: Error: bad register name `%rbx)'
./generate.s:51: Error: bad register name `%rsi'
./generate.s:52: Error: bad register name `%rdx'
./generate.s:54: Error: bad register name `%rbx'
./generate.s:55: Error: bad register name `%rdx'
./generate.s:57: Error: bad register name `%rsi'
./generate.s:59: Error: bad register name `%rsi'
./generate.s:60: Error: bad register name `%rdx'
./generate.s:62: Error: bad register name `%rsi'
./generate.s:63: Error: bad register name `%rdx'
./generate.s:65: Error: bad register name `%rsi'
./generate.s:67: Error: bad register name `%rbx'
./generate.s:68: Error: bad register name `%rbx'
./generate.s:71: Error: bad register name `%rbp'
./generate.s:72: Error: bad register name `%rbp'

P.S. AMD64 ?

#208357

согласен с gramozeka, gdm в зубы и вперёд... как минимум можно посмотреть, где циклится... или в каком сисколе застревает...

[added]
кстати, а что за хитрожопый вызов через (void)?

#208381
gramozeka написал:
чё за синтаксис такой ?

архитектура amd64, синтаксис AT&T

Fat-Zer написал:
кстати, а что за хитрожопый вызов через (void)?

В amd64 передача параметров идет через регистры. Функция возвращает значение через регистр %rax. Для того, чтобы данный регистр ни на что не повлиял, я и решил использовать (void)function_name().

#208972

Проблема решена, задача сделана. Если кому-то интересно, то вся информация под спойлером.

Показать
main.c
text
#include <stdio.h>
#include <stdlib.h>
#include <gpm.h>

int *a;

void graph(void); int *generate(void); void processing(int*, int);

int my_handler(Gpm_Event *event, void *data) { if(event->y == 35) { if((event->x >= 48) && (event->x <= 51)) { exit(0); } if((event->x >= 20) && (event->x <= 27)) { a = generate(); } if((event->x >= 33) && (event->x <= 42)) { processing(a, 30); } } return 0; }

int main() { Gpm_Connect conn; int c; conn.eventMask = GPM_DOWN; conn.defaultMask = ~conn.eventMask; conn.minMod = 0; conn.maxMod = ~0; graph(); Gpm_Open(&conn, 0); gpm_handler = my_handler; while(c = Gpm_Getc(stdin)) {} Gpm_Close(); return 0; }

graph.s

text
.data
  file_name:
    .string "/dev/vcsa2"
  whiteSpace:
    .byte ' ', 0x70
  blueSpace:
    .byte ' ', 0x10
  redSpace:
    .byte ' ', 0x40
  attrib1:
    .byte 0x74
  genBut:
    .byte 'G', 'e', 'n', 'e', 'r', 'a', 't', 'e'
  callBut:
    .byte 'P', 'r', 'o', 'c', 'e', 's', 's', 'i', 'n', 'g'
  quitBut:
    .byte 'Q', 'u', 'i', 't'
  scrn:
    .byte 0, 0, 0, 0

.text .globl graph .type graph, @function graph: pushq %rbp movq %rsp, %rbp /* Открываем файл для записи в видеопамять */ movq $file_name, %rdi movq $2, %rsi xorq %rax, %rax call open /* Считываем параметры экрана */ pushq %rax movq %rax, %rdi movq $scrn, %rsi movq $4, %rdx call read /* Встаем на начало вывода */ movq $scrn, %rcx incq %rcx movq (%rcx), %rax addq $2, %rcx movq (%rcx), %rbx imulq %rbx decq %rcx movq (%rcx), %rbx addq %rbx, %rax shlq $1, %rax addq $4, %rax popq %rdi pushq %rdi movq %rax, %rsi xorq %rdx, %rdx call lseek /* Формируем фоновое изображение */ popq %rdi movq $2048, %r9 white_loop: xorq %rsi, %rsi movq $1, %rdx call lseek movq $whiteSpace, %rsi movq $2, %rdx call write xorq %r8, %r8 decq %r9 cmpq %r9, %r8 jne white_loop movq $2048, %r9 blue_loop: xorq %rsi, %rsi movq $1, %rdx call lseek movq $blueSpace, %rsi movq $2, %rdx call write xorq %r8, %r8 decq %r9 cmpq %r9, %r8 jne blue_loop movq $640, %r9 red_loop: xorq %rsi, %rsi movq $1, %rdx call lseek movq $redSpace, %rsi movq $2, %rdx call write xorq %r8, %r8 decq %r9 cmpq %r9, %r8 jne red_loop /* Кнопка генерации массива */ movq $8746, %rsi xorq %rdx, %rdx call lseek movq $genBut, %rbx genBut_loop: xorq %rsi, %rsi movq $1, %rdx call lseek movq %rbx, %rsi movq $1, %rdx call write movq $attrib1, %rsi call write incq %rbx cmpq $callBut, %rbx jne genBut_loop /* Кнопка для запуска обработки */ movq $10, %rsi call lseek movq $callBut, %rbx callBut_loop: xorq %rsi, %rsi movq $1, %rdx call lseek movq %rbx, %rsi movq $1, %rdx call write movq $attrib1, %rsi call write incq %rbx cmpq $quitBut, %rbx jne callBut_loop /* Кнопка выхода */ movq $10, %rsi call lseek movq $quitBut, %rbx quitBut_loop: xorq %rsi, %rsi movq $1, %rdx call lseek movq %rbx, %rsi movq $1, %rdx call write movq $attrib1, %rsi call write incq %rbx cmpq $scrn, %rbx jne quitBut_loop /* Закрываем файл и выходим из подпрограммы */ call close movq %rbp, %rsp popq %rbp ret

gen.s

text
.data
  file_name:
    .string "/dev/vcsa2"
  attrib1:
    .byte 0x74
  whiteSpace:
    .byte ' ', 0x70
  array:
    .byte 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
  array_end:

.text .globl generate .type generate, @function generate: pushq %rbp movq %rsp, %rbp /* Инициализируем генератор псевдослучайных чисел */ xorq %rdi, %rdi xorq %rax, %rax call time movq %rax, %rdi call srand /* Заполняем массив псевдослучайными числами */ movq $array, %rsi movq $30, %rcx generate_loop: pushq %rcx pushq %rsi call rand xorq %rdx, %rdx movq $10, %rcx divq %rcx popq %rsi movb %dl, (%rsi) addq $1, %rsi popq %rcx loop generate_loop /* Открываем файл для записи в видеопамять */ movq $file_name, %rdi movq $2, %rsi xorq %rax, %rax call open movq %rax, %rdi /* Встаем на нужную позицию видеопамяти */ movq $264, %rsi xorq %rdx, %rdx call lseek /* Записываем массив в видеопамять */ movq $array, %rsi movq $30, %rcx print_loop: pushq %rcx movb (%rsi), %al addb $48, %al movb %al, (%rsi) pushq %rsi xorq %rsi, %rsi movq $1, %rdx call lseek popq %rsi pushq %rsi movq $1, %rdx call write movq $attrib1, %rsi call write xorq %rsi, %rsi movq $1, %rdx call lseek movq $whiteSpace, %rsi movq $1, %rdx call write movq $attrib1, %rsi call write popq %rsi incq %rsi popq %rcx loop print_loop /* Закрываем файл и выходим из подпрограммы */ call close movq $array, %rax movq %rbp, %rsp popq %rbp ret

proc.s

text
.data
  file_name:
    .string "/dev/vcsa2"
  min:
    .byte 'M', 'i', 'n', 'i', 'm', 'u', 'm', ':'
  minPosition:
    .byte 'P', 'o', 's', 'i', 't', 'i', 'o', 'n', ' ', 'o', 'f', ' ', 'm', 'i', 'n', 'i', 'm', 'u', 'm', ':'
  zeroCount:
    .byte 'C', 'o', 'u', 'n', 't', ' ', 'o', 'f', ' ', 'z', 'e', 'r', 'o', ':'
  middlePosition:
    .byte 'M', 'i', 'd', 'd', 'l', 'e', ' ', 'p', 'o', 's', 'i', 't', 'i', 'o', 'n', ' ', 'a', 'f', 't', 'e', 'r', ' ', 'm', 'i', 'n', 'i', 'm', 'u', 'm', ':'
  symbol:
    .byte '0', 0x1E
  blueSpace:
    .byte ' ', 0x10

.text .globl processing .type processing, @function processing: pushq %rbp movq %rsp, %rbp pushq %rdi pushq %rsi /* Открываем файл для записи в видеопамять */ movq $file_name, %rdi movq $2, %rsi xorq %rax, %rax call open popq %rsi popq %rdi pushq %rax /* Находим минимальное значение в массиве */ /* и его позицию */ movq %rdi, %rax movq %rsi, %r10 xorq %rdx, %rdx xorq %rcx, %rcx incq %rcx movb (%rax), %dl xorq %r8, %r8 incq %r8 search_min: cmpb %dl, (%rax) ja next_search_min movb (%rax), %dl movq %rcx, %r8 next_search_min: incq %rax incq %rcx cmpq %rcx, %r10 jge search_min movq $symbol, %rsi movb %dl, (%rsi) /* Записываем в видеопамять минимальное число */ movq %rdi, %rax popq %rdi pushq %rax pushq %rsi movq $4616, %rsi xorq %rdx, %rdx call lseek movq $min, %rsi movq $8, %rcx print_min: pushq %rcx pushq %rsi xorq %rsi, %rsi movq $1, %rdx call lseek popq %rsi pushq %rsi movq $1, %rdx call write movq $symbol, %rsi incq %rsi call write popq %rsi incq %rsi popq %rcx loop print_min xorq %rsi, %rsi movq $1, %rdx call lseek movq $blueSpace, %rsi movq $2, %rdx call write xorq %rsi, %rsi movq $1, %rdx call lseek movq $symbol, %rsi movq $2, %rdx call write /* Записываем в видеопамять позицию минимального числа */ movq $236, %rsi movq $1, %rdx call lseek movq $minPosition, %rsi movq $20, %rcx print_min_position: pushq %rcx pushq %rsi xorq %rsi, %rsi movq $1, %rdx call lseek popq %rsi pushq %rsi movq $1, %rdx call write movq $symbol, %rsi incq %rsi call write popq %rsi incq %rsi popq %rcx loop print_min_position xorq %rsi, %rsi movq $1, %rdx call lseek movq $blueSpace, %rsi movq $2, %rdx call write movq %r8, %rax xorq %rdx, %rdx movq $10, %rcx divq %rcx addb $48, %al addb $48, %dl pushq %rdx pushq %rax xorq %rsi, %rsi movq $1, %rdx call lseek popq %rax movq $symbol, %rsi movb %al, (%rsi) movq $2, %rdx call write xorq %rsi, %rsi movq $1, %rdx call lseek popq %rdx movq $symbol, %rsi movb %dl, (%rsi) movq $2, %rdx call write popq %rsi popq %rax pushq %rdi movq %rax, %rdi /* Находим количество нулей до минимального */ movq %rdi, %r9 xorq %r10, %r10 xorq %rdx, %rdx incq %r10 xorq %rcx, %rcx xorq %rax, %rax search_zero: movb (%r9), %al subb $48, %al cmpb %al, %cl jne next_search_zero incq %rdx next_search_zero: incq %r9 incq %r10 cmpq %r10, %r8 jne search_zero movq %rdx, %r9 /* Записываем в видеопамять количество нулей до минимального числа */ popq %rdi pushq %rsi movq $210, %rsi movq $1, %rdx call lseek movq $zeroCount, %rsi movq $14, %rcx print_zero_count: pushq %rcx pushq %rsi xorq %rsi, %rsi movq $1, %rdx call lseek popq %rsi pushq %rsi movq $1, %rdx call write movq $symbol, %rsi incq %rsi call write popq %rsi incq %rsi popq %rcx loop print_zero_count xorq %rsi, %rsi movq $1, %rdx call lseek movq $blueSpace, %rsi movq $2, %rdx call write movq %r9, %rax xorq %rdx, %rdx movq $10, %rcx divq %rcx addb $48, %al addb $48, %dl pushq %rdx pushq %rax xorq %rsi, %rsi movq $1, %rdx call lseek popq %rax movq $symbol, %rsi movb %al, (%rsi) movq $2, %rdx call write xorq %rsi, %rsi movq $1, %rdx call lseek popq %rdx movq $symbol, %rsi movb %dl, (%rsi) movq $2, %rdx call write popq %rsi /* Находим среднее положение после минимального */ movq $30, %rax subq %r8, %rax shr $1, %rax addq %r8, %rax incq %rax pushq %rax /* Записываем в видеопамять среднее положение после минимального числа */ movq $222, %rsi movq $1, %rdx call lseek movq $middlePosition, %rsi movq $30, %rcx print_middle: pushq %rcx pushq %rsi xorq %rsi, %rsi movq $1, %rdx call lseek popq %rsi pushq %rsi movq $1, %rdx call write movq $symbol, %rsi incq %rsi call write popq %rsi incq %rsi popq %rcx loop print_middle xorq %rsi, %rsi movq $1, %rdx call lseek movq $blueSpace, %rsi movq $2, %rdx call write popq %rax xorq %rdx, %rdx movq $10, %rcx divq %rcx addb $48, %al addb $48, %dl pushq %rdx pushq %rax xorq %rsi, %rsi movq $1, %rdx call lseek popq %rax movq $symbol, %rsi movb %al, (%rsi) movq $2, %rdx call write xorq %rsi, %rsi movq $1, %rdx call lseek popq %rdx movq $symbol, %rsi movb %dl, (%rsi) movq $2, %rdx call write /* Закрываем файл и выходим из подпрограммы */ call close movq %rbp, %rsp popq %rbp ret

Компиляция:
[console]$ gcc ./main.c ./graph.s ./gen.s ./proc.s -lgpm[/console]

Запуск от рута на второй виртуальной консоли.

Благодарю всех, кто помогал мне это сделать.

Войдите или зарегистрируйтесь, чтобы ответить.