Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Последние темы форума

Показать новые сообщения »

Почтовая рассылка

Подписчиков: 6462
Последний выпуск: 19.06.2015

Как реализовать мультизадачность в BorlandC++ ?

87K
16 декабря 2012 года
densvr
2 / / 15.12.2012
Нужно написать программу, состоящую из двух функций с бесконечными циклами и прерыванием, переключающем эти функции. Например код ниже должен переключать функцию, печатающую '1' на функцию, печатающую '2'
Преподаватель объяснял, что для этого как минимум нужно восстановить [bp+18] и [bp+20] для функции, на которую нужно переключаться.

======Пример 1: Здесь я восстанавливаю все bp вплоть до [bp+22], при первом выходе происходит переключение и печатается '2' вместо '1', затем все зависает. В отладчике все в порядке. Код:


Код:
#include <stdio.h>
#include <conio.h>
#include <dos.h>





void p1() {
   while (2) {
       disable();
       asm {
      mov ax,0xb800
      mov es,ax
      add bx,1
      mov ax,'1'
      mov es:[bx],al
       }
       enable();
       int a=1;
   }
}

void p2() {
   while (1) {
       disable();
       asm {
      mov ax,0xb800
      mov es,ax
      add bx,1
      mov ax,'2'
      mov es:[bx],al
       }
       enable();
       int a=1;
   }
}



unsigned char* Context=new unsigned char[22];

void interrupt swap(...) {    

   asm {
    lea bx,Context
    mov cx,0
    push bp
    }

    SwapContextLoop:
    asm {
    mov ax,[bx]
    mov dx,[bp]
    mov [bx],dx
    mov [bp],ax

    add cx,2
    add bx,2
    add bp,2

    cmp cx,24
       jne SwapContextLoop

    pop bp
    }


}




void main() {


   for(int i=0; i<22; i++)
      *(Context+i)=0;
   asm {
      lea bx,Context
      lea dx,pp;
      mov [bx+18],dx
      mov ax,cs
      mov [bx+20],ax
   }

   setvect(0x09,&swap);
   
   p1();

}


======Пример 2: Пытаюсь просто перезаписать указатели на функции p1() и p2() в [bp+18]. Абсолютно тот же результат что и в первом примере. Код:


Код:
#include <stdio.h>
#include <dos.h>
#include <conio.h>



void p1() {
   while (count<20) {
       disable();
       asm {
      mov ax,0xb800
      mov es,ax
      mov bx,0
      mov ax,'1'
      mov es:[bx],al
       }
       enable();
       int a=1;

   }
}



void p2() {
   asm mov bx,0
   while (count<20) {
       disable();
       asm {
      mov ax,0xb800
      mov es,ax
      mov bx,0
      mov ax,'2'
      mov es:[bx],al
       }
       enable();
       int a=1;

   }
}


void interrupt swap(...) {
   asm {
    mov ax,0
    mov [bp],ax
    mov [bp+2],ax
    mov [bp+4],ax
    mov [bp+6],ax
    mov [bp+8],ax
    mov [bp+10],ax
    mov [bp+12],ax
    mov [bp+14],ax
    mov [bp+16],ax
    mov [bp+18],ax
    mov [bp+20],ax
    mov [bp+22],ax
    }

    static int i=0;
    if (i==0) {
       i=1;
       asm {

      lea bx,pp
      mov [bp+18],bx
      mov ax,cs
      mov [bp+20],ax
       }
    }
    else {
       i=0;
       asm {
      lea bx,p
      mov [bp+18],bx
      mov ax,cs
      mov [bp+20],ax
       }
    }

}




void main() {
   setvect(0x09,swap);
   p1();

}
1
16 декабря 2012 года
kot_
7.3K / / 20.01.2000
иии?
вопрос в чем?
344
16 декабря 2012 года
P*t*
474 / / 15.02.2007
Вопрос понятно в чем - описано что хотелось и что получилось, ожидается что кто-нибудь объяснит, почему получилось не то.

Но мне вот абсолютно не понятно, как это вообще должно работать. В функции swap меняются местами области в 24 байта по адресам bx и bp. Инициализации bx и bp не видно. Вот как это может работать?
87K
16 декабря 2012 года
densvr
2 / / 15.12.2012
Цитата: P*t*
Вопрос понятно в чем - описано что хотелось и что получилось, ожидается что кто-нибудь объяснит, почему получилось не то.

Но мне вот абсолютно не понятно, как это вообще должно работать. В функции swap меняются местами области в 24 байта по адресам bx и bp. Инициализации bx и bp не видно. Вот как это может работать?



В примере 1 инициализация массива Context происходит в функции main:

 
Код:
for(int i=0; i<22; i++)
      *(Context+i)=0;
   asm {
      lea bx,Context
      lea dx,pp;
      mov [bx+18],dx
      mov ax,cs
      mov [bx+20],ax
   }

Затем, при каждом запуске swap(), bx привязывается к Context

 
Код:
asm {
    lea bx,Context
Возможно я ошибаюсь насчет регистра bp. Как я понял из объяснения преподавателя, этот регистр в прерывании Swap и в функциях p1() и p2() указывает на один и тот же участок памяти, поэтому я просто меняю этот участок памяти ( [bp+0] ... [bp+22] ) в прерывании, восстанавливая при этом контекст пассивной функции и переключаясь на нее. Точнее так должно быть.

Угробил полтора месяца на этот пример. Было бы здорово разобраться почему это не работает и сделать рабочий вариант
239
17 декабря 2012 года
koderAlex
1.4K / / 07.09.2005
вы стек портите . вот и не работает .
вам надо при инициализации задачи создать копии сегментов стека и данных , а при прерывании просто менять значения сегментных регистров , предварительно сохранив контекст в текущий стек .

Знаете кого-то, кто может ответить? Поделитесь с ним ссылкой.

Ваш ответ

Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог