Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Низкоуровневое программирование > Assembler - Ассемблер (FASM, MASM, WASM, NASM, GoASM, Gas, RosAsm, HLA) и не рекомендуем TASM
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 27.10.2011, 00:26   #1
Osanve
Пользователь
 
Аватар для Osanve
 
Регистрация: 11.12.2010
Сообщений: 50
По умолчанию Работа с видеопамятью и мышью

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

Что имеется?
Цитата:
1) ASUS EeePC 1001PXD
2) GNU/Linux Debian squeeze amd64
3) gcc 4.4.5
Что требуется?
Цитата:
Программа, выводящая в консоли три цветных окна. В первом окне осуществляется ввод. Во втором окне вывод. В третьем окне меню. Нужна поддержка мыши.
Код для обработки введенных данных берется из прошлой лабораторной работы, которая успешно сделано (просто текстовый ввод и вывод на GAS'е проблем не вызывает).

main.s
Код:
.data
  print_format:
    .string "\n"
  print_format_array:
    .string "%d "
  print_format_result:
    .string "%s%d\n"
  print_min:
    .string "Минимальное значение в массиве: "
  print_min_pos:
    .string "Положение минимального значения: "
  print_zero_count:
    .string "Количество нулей до минимального значения: "
  print_middle:
    .string "Среднее положение после минимального: "
  array:
    .quad 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 main
  .type  main, @function
  main:
    pushq %rbp
    movq  %rsp,                 %rbp

    movq  $0,                   %rdi
    call  time
    movq  %rax,                 %rdi
    call  srand
    movq  $array,               %rbx
  generate_loop:
    call  rand
    xorq  %rdx,                 %rdx
    movq  $10,                  %rcx
    divq  %rcx
    movq  %rdx,                 (%rbx)
    addq  $8,                   %rbx
    cmpq  $array_end,           %rbx
    jne   generate_loop
    movq  $array,               %rbx
  print_loop:
    movq  (%rbx),               %rsi
    xorq  %rax,                 %rax
    movq  $print_format_array,  %rdi
    call  printf
    addq  $8,                   %rbx
    cmpq  $array_end,           %rbx
    jne   print_loop
    movq  $print_format,        %rdi
    xorq  %rax,                 %rax
    call  printf
    movq  $30,                  %rsi
    movq  $array,               %rdi
    call  _Z10processingPii
    movq  %rax,                 %rbx
    movq  (%rbx),               %rdx
    movq  $print_min,           %rsi
    movq  $print_format_result, %rdi
    xorq  %rax,                 %rax
    call  printf
    addq  $8,                   %rbx
    movq  (%rbx),               %rdx
    movq  $print_min_pos,       %rsi
    movq  $print_format_result, %rdi
    xorq  %rax,                 %rax
    call  printf
    addq  $8,                   %rbx
    movq  (%rbx),               %rdx
    movq  $print_zero_count,    %rsi
    movq  $print_format_result, %rdi
    xorq  %rax,                 %rax
    call  printf
    addq  $8,                   %rbx
    movq  (%rbx),               %rdx
    movq  $print_middle,        %rsi
    movq  $print_format_result, %rdi
    xorq  %rax,                 %rax
    call  printf

    movq  %rbp,                 %rsp
    popq  %rbp
    ret
processing.s
Код:
.data
  result:
    .quad 0, 0, 0, 0
  result_end:

.text
  .globl _Z10processingPii
  .type  _Z10processingPii, @function
  _Z10processingPii:
    pushq %rbp
    movq  %rsp,    %rbp

    movq  %rdi,    %rax
    movq  %rsi,    %rdx
    xorq  %rcx,    %rcx
    incq  %rcx
    movq  (%rax),  %rbx
    xorq  %r8,     %r8
    incq  %r8
  search_min:
    cmpq  %rbx,    (%rax)
    ja    next_search_min
    movq  (%rax),  %rbx
    movq  %rcx,    %r8
  next_search_min:
    addq  $8,      %rax
    incq  %rcx
    cmpq  %rcx,    %rdx
    jge   search_min
    movq  $result, %r9
    movq  %rbx,    (%r9)
    addq  $8,      %r9
    movq  %r8,     (%r9)

    movq  %rdi,    %rax
    xorq  %rbx,    %rbx
    xorq  %rdx,    %rdx
    incq  %rdx
    xorq  %rcx,    %rcx
  search_zero:
    cmpq  (%rax),  %rcx
    jne   next_search_zero
    incq  %rbx
  next_search_zero:
    addq  $8,      %rax
    incq  %rdx
    cmpq  %rdx,    %r8
    jne   search_zero
    addq  $8,      %r9
    movq  %rbx,    (%r9)

    movq  %rsi,    %rax
    subq  %r8,     %rax
    shr   $1,      %rax
    addq  %r8,     %rax
    incq  %rax
    movq  $31,     %rbx
    cmpq  %rax,    %rbx
    jne   next
    movq  $-1,     %rax
  next:
    addq  $8,      %r9
    movq  %rax,    (%r9)

    movq  $result, %rax

    movq  %rbp,    %rsp
    popq  %rbp
    ret
А вот как все это сделать в графическом режиме (требуется прямая запись в видеопамять) и с поддержкой мыши уже проблема.
Информации по этой теме я не нашел.
В C есть возможность использовать библиотеку ncurses, следовательно (теоретически) можно скомпилировать нужный код на C с флагом -S, а потом изучать ассемблер, но это, извините меня, извращение (мне хватило такого изучения на первую лабораторную ).

Собственно возникает вопрос как поставленную задачу можно реализовать?

Буду рад любым мыслям по теме, ссылкам на статьи и указанием на подходящие книги.

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

Последний раз редактировалось Osanve; 27.10.2011 в 00:30.
Osanve вне форума Ответить с цитированием
Старый 27.10.2011, 21:36   #2
asmars
Форумчанин
 
Аватар для asmars
 
Регистрация: 28.05.2011
Сообщений: 309
По умолчанию

Думаю Вам стоит перейти на ФАСМ, мне кажеться так легче будет.
Адрес видео памяти 0А000h .

Пока что все что могу подсказать.
Спеши медленно.
asmars вне форума Ответить с цитированием
Старый 27.10.2011, 22:19   #3
Osanve
Пользователь
 
Аватар для Osanve
 
Регистрация: 11.12.2010
Сообщений: 50
По умолчанию

Цитата:
Сообщение от asmars Посмотреть сообщение
Думаю Вам стоит перейти на ФАСМ, мне кажеться так легче будет.
Если переходить на FASM, то значит надо учить новый синтаксис. В принципе попытки были, но он показался интуитивно неясным. Да и в третий раз писать код (сдавал на 32-х разрядах, потом переводил на 64), который делает все то же самое мне, если честно, лень.

Цитата:
Сообщение от asmars Посмотреть сообщение
Адрес видео памяти 0А000h .
A000:0000 - страница видеопамяти для 16-ти битной системы, а я использую 64-х, т.ч. скорее всего адрес будет другой. Правильным вариантом было бы попробовать, но вот незадача: для перехода в видеорежим (13h) требуется 10-ое прерывание (int 10h), в то время как в GAS'е, если я не ошибаюсь, используется только int 0x80 (аналог int 21h, т.е. через это прерывание можно сделать все). Изучал файл /usr/include/asm/unistd_64.h (файл системных вызовов, т.е., например, чтобы вывести текст через прерывания используется именно он), но ничего похожего на обращение к видеопамяти не нашел. Также в директориях /usr/include/asm и /usr/include/asm-generic тоже ничего похожего нет.
Osanve вне форума Ответить с цитированием
Старый 27.10.2011, 22:29   #4
Пепел Феникса
Старожил
 
Аватар для Пепел Феникса
 
Регистрация: 28.01.2009
Сообщений: 21,000
По умолчанию

Цитата:
A000:0000 - страница видеопамяти для 16-ти битной системы, а я использую 64-х, т.ч. скорее всего адрес будет другой.
у вас дебиан, консольная?
адрес то по умолчанию тот же, врятли он изменен.
Цитата:
в то время как в GAS'е, если я не ошибаюсь, используется только int 0x80
ну использовать то можете что хотите, но если не ошибаюсь, то там ведется работа в защищенном режиме(а то и в широком защищенном) и сервисы биос недоступны.
а 80h это вызовы ядра если память не изменяет.

далее, судя по заданию, вы уверены что это вообще для линукса? обычно такие вещи под ДОСом делают.
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
Программа делает то что написал программист, а не то что он хотел.
Функции/утилиты ждут в параметрах то что им надо, а не то что вы хотите.
Пепел Феникса вне форума Ответить с цитированием
Старый 27.10.2011, 23:23   #5
Osanve
Пользователь
 
Аватар для Osanve
 
Регистрация: 11.12.2010
Сообщений: 50
По умолчанию

Цитата:
Сообщение от Пепел Феникса Посмотреть сообщение
у вас дебиан, консольная?
адрес то по умолчанию тот же, врятли он изменен.
Можно в терминале, можно в виртуальной консоли. Мне без разницы.

Цитата:
Сообщение от Пепел Феникса Посмотреть сообщение
адрес то по умолчанию тот же, врятли он изменен.
Адресация, если я не ошибаюсь, все равно будет отличаться.

Цитата:
Сообщение от Пепел Феникса Посмотреть сообщение
ну использовать то можете что хотите, но если не ошибаюсь, то там ведется работа в защищенном режиме(а то и в широком защищенном) и сервисы биос недоступны.
а 80h это вызовы ядра если память не изменяет.
Да, в защищенном.

Цитата:
Сообщение от Пепел Феникса Посмотреть сообщение
а 80h это вызовы ядра если память не изменяет.
Да, именно они. Там от read, write, open и до reboot, chmod и пр.

Цитата:
Сообщение от Пепел Феникса Посмотреть сообщение
далее, судя по заданию, вы уверены что это вообще для линукса? обычно такие вещи под ДОСом делают.
Методички по дисциплине написаны для DOS'а, но я располагаю только Linux'ом. Преподаватель разрешает. Как вариант, можно делать все задания в аудитории, но компы там слишком уж тормазнутые

Случайно наткнулся на отсыл к vcs. В мане давался пример программы, который отображает символ и атрибуты экрана (Что это такое? У меня постоянно выводит 0x07) в позиции курсора на второй виртуальной консоли, а затем меняет там цвет фона.
Код:
#include <unistd.h>
#include <stdio.h>
#include <fcntl.h>

int main()
{
  int fd;
  struct {char lines, cols, x, y;} scrn;
  char ch, attrib;

  fd = open("/dev/vcsa2", O_RDRW);
  (void)read(fd, &scrn, 4);
  (void)lseek(fd, 4 + 2*(scrn.y*scrn.cols + scrn.x), 0);
  (void)read(fd, &ch, 1);
  (void)read(fd, &attrib, 1);
  printf("ch='%c' attrib=0x%02x\n", ch, attrib);
  attrib ^= 0x10;
  (void)lseek(fd, -1, 1);
  (void)write(fd, &attrib, 1);
  return 0;
}
В этом коде никак не могу понять почему в функции передаются именно такие параметры и никак иначе, а без этого понимания изучать ассемблерный код себе дороже, имхо.
Osanve вне форума Ответить с цитированием
Старый 27.10.2011, 23:46   #6
asmars
Форумчанин
 
Аватар для asmars
 
Регистрация: 28.05.2011
Сообщений: 309
По умолчанию

Цитата:
сервисы биос недоступны.
на счет этого, как мне сказали это решается прерыванием 31h.
вот почитать можно о нем..
http://avprog.narod.ru/tmt/SupportedDPMI.html
Спеши медленно.
asmars вне форума Ответить с цитированием
Старый 28.10.2011, 00:03   #7
Osanve
Пользователь
 
Аватар для Osanve
 
Регистрация: 11.12.2010
Сообщений: 50
По умолчанию

Цитата:
Сообщение от asmars Посмотреть сообщение
Там используется 32-х разрядная версия. По опыту перевода с 32-х на 64 разряда, могу сказать, что отличия порой не маленькие.
Также там используется DOS (вот например: http://www.avprog.narod.ru/tmt/SupportedDPMI.html#37), следовательно прерывания будут отличаться (в качестве сравнения беру вывод текста в DOS и Linux средствами ассемблера). Или я что-то не понимаю?
Osanve вне форума Ответить с цитированием
Старый 28.10.2011, 00:11   #8
asmars
Форумчанин
 
Аватар для asmars
 
Регистрация: 28.05.2011
Сообщений: 309
По умолчанию

увы, под линь асм код никогда не писал.

кстати как я понимаю, Вы, Osanve, бывалый в кодинге под линь. такой вопрос к Вам, под что удобнее/проще/нужнее писать под линь или вин ?
Спеши медленно.
asmars вне форума Ответить с цитированием
Старый 28.10.2011, 00:46   #9
Osanve
Пользователь
 
Аватар для Osanve
 
Регистрация: 11.12.2010
Сообщений: 50
По умолчанию

Цитата:
Сообщение от asmars Посмотреть сообщение
под что удобнее/проще/нужнее писать под линь или вин ?
Удобство это субъективное понятие. Для кого-то эталон удобства - MS VS, а для кого-то vim. Т.ч. в этом плане лучше попробовать и то и другое, а потом решить.
На счет простоты... Языки программирования в принципе везде одинаковые, есть различия только в их реализации в каком-то определенном компиляторе. Классический пример, который я привожу по данному поводу:
Код:
#include <iostream>

using namespace std;

int main()
{
    int n;
    cin >> n;
// gcc позволяет выполнить следующую конструкцию (Страуструп приводил в
//     своей книге примеры именно с использованием компилятора gcc):
//    switch (n)
//    {
//    case 1 ... 4: cout << "few" << endl; break;
//    case 5 ... 9: cout << "several" << endl; break;
//    case 10 ... 19: cout << "pack" << endl; break;
//    case 20 ... 49: cout << "lots" << endl; break;
//    case 50 ... 99: cout << "horde" << endl; break;
//    case 100 ... 249: cout << "throng" << endl; break;
//    case 250 ... 499: cout << "swarm" << endl; break;
//    case 500 ... 999: cout << "zounds" << endl; break;
//    default: cout << "legion" << endl; break;
//    }
// Но MS VC++ мудак, и приходится использовать следующий быдлокод:
    if((n >= 1) && (n <= 4))
    {
        cout << "few" << endl;
    }
    else
    {
        if((n >= 5) && (n <= 9))
        {
            cout << "several" << endl;
        }
        else
        {
            if((n >= 10) && (n <= 19))
            {
                cout << "pack" << endl;
            }
            else
            {
                if((n >= 20) && (n <= 49))
                {
                    cout << "lots" << endl;
                }
                else
                {
                    if((n >= 50) && (n <= 99))
                    {
                        cout << "horde" << endl;
                    }
                    else
                    {
                        if((n >= 100) && (n <= 249))
                        {
                            cout << "throng" << endl;
                        }
                        else
                        {
                            if((n >= 250) && (n <= 499))
                            {
                                cout << "swarm" << endl;
                            }
                            else
                            if((n >= 500) && (n <= 999))
                            {
                                cout << "zounds" << endl;
                            }
                            else
                            {
                                cout << "legion" << endl;
                            }
                        }
                    }
                }
            }
        }
    }
    return 0;
}
Ну а писать нужно и туда и туда. Есть области, неохваченные программными продуктами ни в одной ОС, а если и затрагивают, то криво. Правда, если основной целью является зарабатывание денег на софте, то Вам только под винду, а если иначе, то добро пожаловать к нам
P.S. ИМХО
Osanve вне форума Ответить с цитированием
Старый 28.10.2011, 12:15   #10
Пепел Феникса
Старожил
 
Аватар для Пепел Феникса
 
Регистрация: 28.01.2009
Сообщений: 21,000
По умолчанию

Цитата:
На счет простоты... Языки программирования в принципе везде одинаковые, есть различия только в их реализации в каком-то определенном компиляторе.
да чаще в АПИ.
Цитата:
Можно в терминале, можно в виртуальной консоли. Мне без разницы.
просто, там совсем все иначе, прямого доступа к памяти терминала по сути и нет(лишь если через устройство-файл)
Цитата:
Адресация, если я не ошибаюсь, все равно будет отличаться.
нет, она отличается изза того что у вас ОС, которая уже многое изменила под себя.(да и думаю как и в винде идет принцип виртуального адресного пространства)
Цитата:
Методички по дисциплине написаны для DOS'а, но я располагаю только Linux'ом.
поставьте какойнить будь DOSBox, или иную виртуалку(на которую уже грузите ДОС)
так самое верное помоему, а то ведь вам в аудитории же показывать поидее вашу программу.
Цитата:
и атрибуты экрана (Что это такое?
аттрибуты экрана, это цвет символа, цвет фона знакоместа и бит мерцания.
Цитата:
В этом коде никак не могу понять почему в функции передаются именно такие параметры и никак иначе, а без этого понимания изучать ассемблерный код себе дороже, имхо.
к lseek передается адрес нужной информации, по сути говоря, scrn.x и scrn.y можно заменить на нужные вам координаты.
там первые 4байта этого файла это информация терминала(ширина и высота, а также позиция курсора) и далее идут данные уже, байт символ и байт его аттрибутов(и так для всех)
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
Программа делает то что написал программист, а не то что он хотел.
Функции/утилиты ждут в параметрах то что им надо, а не то что вы хотите.
Пепел Феникса вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Работа на прямую с видеопамятью asmars Assembler - Ассемблер (FASM, MASM, WASM, NASM, GoASM, Gas, RosAsm, HLA) и не рекомендуем TASM 17 01.08.2011 16:05
Перехват прерываний от клавиатуры и работа с видеопамятью sunlightik Assembler - Ассемблер (FASM, MASM, WASM, NASM, GoASM, Gas, RosAsm, HLA) и не рекомендуем TASM 2 26.02.2010 00:32
работа с мышью! _Timon Помощь студентам 1 20.01.2009 23:29
Работа с видеопамятью IgorArhangel Общие вопросы C/C++ 0 20.12.2008 22:46
Работа с мышью Amery Assembler - Ассемблер (FASM, MASM, WASM, NASM, GoASM, Gas, RosAsm, HLA) и не рекомендуем TASM 4 28.05.2008 21:19