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

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

Вернуться   Форум программистов > IT форум > Помощь студентам
Регистрация

Восстановить пароль

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

Ответ
 
Опции темы Поиск в этой теме
Старый 03.04.2015, 20:37   #1
O'neeL
Пользователь
 
Аватар для O'neeL
 
Регистрация: 10.12.2011
Сообщений: 36
По умолчанию Фиктивная многопоточность в MS-DOS (C++)

Привет всем!
По учебе нужно реализовать решение классической задачи "обедающие философы". С этим бы проблем не было если не особенности.
Написать нужно под DOS на плюсах с использованием прерываний от таймера (нужно реализовать некое подобие многопоточности). С обработкой прерываний проблем так же нет.
А вот в чем проблема есть. Как я понимаю (точнее как я вычитал), для реализации этого дела, в прерывании мне нужно сохранять точку возврата из него, переключать поток (по сути менять номер текущего процесса) и заменять точку возврата на заранее сохраненную для текущего процесса. Именно это я не знаю как сделать, гугл не помог, возможно я не могу правильно задать ему вопрос . Прошу дать ссылок, или написать что стоит погуглить.
O'neeL вне форума Ответить с цитированием
Старый 04.04.2015, 09:37   #2
alexcoder
Форумчанин
 
Регистрация: 31.05.2009
Сообщений: 786
По умолчанию

Пример подобного изврата.

Код:
#include <stdio.h> 
#include <dos.h> 
#include <mem.h> 
#include <conio.h> 
 
struct ProcStats //struktura soderjashaya kontext zadachi 
{ 
    unsigned int rax, rbx, rcx, rdx; // 0  2  4  6 
    unsigned int rsi, rdi, rbp, rsp; // 8 10 12 14 
    unsigned int rcs, rds, res, rss; //16 18 20 22 
    unsigned int rip, rflags, a, b;  //24 26 28 30 
} Stats[3]; //massiv iz treh takih struktur 
unsigned int current_proc; //nomer tekushey zadachi 
unsigned int stats_offset; //adres konteksta zadachi 
void interrupt (*oldHandler)(...); //ukazatel na staryi obrabotchik preryvaniya 
void interrupt IntHandler(...) //svoy obrabotchik 
{ 
    asm { 
  mov  si, [current_proc]; //nomer procedury 
  mov  cl, 5 //umnojaem nar 32 (razmer struktury) 
  shl  si, cl 
  //mov  ax, offset Stats 
  mov  ax, [stats_offset] //pribavlyaem adres nachala massiva struktur
  add  si, ax  //poluchaem adres nujnogo konteksta 
  pop  ax      //zapisyvaem v nego registry 
  mov  [si+12], ax
  pop  ax 
  mov  [si+10], ax
  pop  ax 
  mov  [si+ 8], ax
  pop  ax 
  mov  [si+18], ax
  pop  ax 
  mov  [si+20], ax
  pop  ax 
  mov  [si+ 6], ax
  pop  ax
  mov  [si+ 4], ax
  pop  ax 
  mov  [si+ 2], ax
  pop  ax 
  mov  [si+ 0], ax
  pop  ax 
  mov  [si+24], ax
  pop  ax 
  mov  [si+16], ax
  pop  ax 
  mov  [si+26], ax
  mov  ax, sp 
  mov  [si+14], ax
  mov  ax, ss
  mov  [si+22], ax

  mov  ax, [current_proc] //perehodim k sleduyushey zadache
  inc  ax 
  cmp  ax, 3 
  jb label1 
  mov  ax, 0 
    } 
    label1: 
    asm {
mov  [current_proc], ax //vychislyaem adres eyo konteksta
  mov  si, ax 
  mov  cl, 5 
  shl  si, cl 
  //mov  ax, offset Stats 
  mov  ax, [stats_offset]
  add  si, ax       //zagrujaem registry 
  mov  ax, [si+22]
  mov  ss, ax 
  mov  ax, [si+14]
  mov  sp, ax 
  mov  ax, [si+26] 
  push ax 
  mov  ax, [si+16]
  push ax 
  mov  ax, [si+24]
  push ax 
  mov  ax, [si+ 0]
  push ax 
  mov  ax, [si+ 2]
  push ax 
  mov  ax, [si+ 4]
  push ax 
  mov  ax, [si+ 6]
  push ax 
  mov  ax, [si+20]
  push ax 
  mov  ax, [si+18]
  push ax 
  mov  ax, [si+ 8]
  push ax 
  mov  ax, [si+10]
  push ax 
  mov  ax, [si+12]
  push ax 
    } 
    oldHandler(); //vyzyvaem staryi obrabotchik 
} 
 
void Proc1(void); 
void Proc2(void); 
void Proc3(void); 
 
int main(void) 
{ 
    unsigned int i, rd, rc, re, rs, ri0, ri1, ri2, f; 
 
    for(i=0;i<3;i++)
memset(&Stats[i],0,sizeof(ProcStats)); 
    asm {   //zapisyvaem registry vo vremennye peremennye 
  mov  ax, cs 
  mov  [rc], ax 
  mov  ax, ds 
  mov  [rd], ax 
  mov  ax, es 
  mov  [re], ax 
  mov  ax, ss 
  mov  [rs], ax 
  mov  [ri0], offset Proc1 //adresa nachala procedur 
  mov  [ri1], offset Proc2 
  mov  [ri2], offset Proc3 
  pushf
  pop  ax
  mov  [f], ax
    }
    for(i=0;i<3;i++) //zapisyvaem znacheniya segmentnyh registrov,
    {                //flagov 
  Stats[i].rcs = rc;  //i adresa nacha procedur 
  Stats[i].rds = rd;  //v sootvetstvuyushye konteksty 
  Stats[i].res = re; 
  Stats[i].rss = rs; 
  Stats[i].rflags = f; 
    } 
    Stats[0].rip = ri0; 
    Stats[1].rip = ri1;
    Stats[2].rip = ri2; 
    current_proc = 0; //tekushaya procedura - pervaya 
    stats_offset = (unsigned)&Stats; //adres nachala massiva
    oldHandler = getvect(0x9); //perekluchaemsya po najatiyu klavishy
    setvect(0x8,IntHandler); 
    Proc1(); 
    setvect(0x8,oldHandler); 
 
    return 0; 
} 
 
void Proc1(void) 
{ 
asm{
	mov ax,0b800h
	mov es,ax
	xor bp,bp
	}
m10:    asm{
	mov di,0
	mov cx,bp
	jcxz m13
	mov ax,09dbh
	rep stosw
	}
m13:	asm{
	mov cx,80
	sub cx,bp
	jcxz m12
	mov ax,0900h
	rep stosw
	mov cx,0
	}
m11:    asm{
	loop m11}
m12:    asm{
	inc bp	
	cmp bp,80
	jna m10	
	mov bp,0
	jmp m10	
	}

   }
 
void Proc2(void)
{
asm{
	mov ax,0b800h
	mov es,ax
	xor bp,bp
	}
m20:    asm{
	mov di,160
	mov cx,bp
	jcxz m23
	mov ax,0adbh
	rep stosw
	}
m23:	asm{
	mov cx,80
	sub cx,bp
	jcxz m22
	mov ax,0a00h
	rep stosw
	mov cx,0
	}
m21:    asm{
	loop m21}
m22:    asm{
	inc bp	
	cmp bp,80
	jna m20	
	mov bp,0
	jmp m20	
	}

   }

 
void Proc3(void) 
{ 
asm{
	mov ax,0b800h
	mov es,ax
	xor bp,bp
	}
m30:    asm{
	mov di,320
	mov cx,bp
	jcxz m33
	mov ax,0bdbh
	rep stosw
	}
m33:	asm{
	mov cx,80
	sub cx,bp
	jcxz m32
	mov ax,0b00h
	rep stosw
	mov cx,0
	}
m31:    asm{
	loop m31}
m32:    asm{
	inc bp	
	cmp bp,80
	jna m30	
	mov bp,0
	jmp m30	
	}
}
Помощь с программами:
vk.com/alexcoder1
e-mail: informatik101@mail.ru
alexcoder вне форума Ответить с цитированием
Старый 04.04.2015, 12:39   #3
O'neeL
Пользователь
 
Аватар для O'neeL
 
Регистрация: 10.12.2011
Сообщений: 36
По умолчанию

Спасибо! Опробую. Изврат или не изврат, но делать надо .
O'neeL вне форума Ответить с цитированием
Старый 04.04.2015, 21:29   #4
O'neeL
Пользователь
 
Аватар для O'neeL
 
Регистрация: 10.12.2011
Сообщений: 36
По умолчанию

Попробовал, в обработчике прерывания сохранение регистров неудается (виртуалка виснет намертво).
Код: http://pastebin.com/eHWT8DEi
Прошу не обращать внимания на обилие define, сам я не пишу на плюсах и меня эта воможность забавляет, вот я и использую их к месту и нет.
O'neeL вне форума Ответить с цитированием
Ответ


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



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
WmWare и DOS, как скопировать в DOS файлы zla9_kolu4ka Операционные системы общие вопросы 0 15.01.2015 18:06
Многопоточность Fahman Общие вопросы Delphi 21 18.01.2014 12:59
С++ многопоточность kineziz Общие вопросы C/C++ 3 11.09.2012 13:20
Многопоточность kroŧ Общие вопросы Delphi 5 21.06.2010 10:47
Многопоточность CrazyDude Общие вопросы Delphi 1 18.04.2010 19:00