LinuxForum.Fans
Тема

Помогите разобраться в не большом коде *.CPP

Автор: webber 6 сообщений 1602 просмотров
#356700

Привет всем!
Есть программа реализующая алгоритм обедающих философов по таймеры (аппаратному прерыванию) 0х08 реализует якобы параллельно (DosBox & Turbo C)

text

#include <conio.h>
#include <stdlib.h>
#include <stdio.h>
#include <dos.h>

const int N = 5; const int sDELAY=1500; const int lDELAY=3000;

struct Registers { unsigned int BP; unsigned int DI; unsigned int SI; unsigned int DS; unsigned int ES; unsigned int DX; unsigned int CX; unsigned int BX; unsigned int AX; unsigned int IP; unsigned int CS; unsigned int FLAGS; };

struct context { unsigned int SP; unsigned int bloat[1000]; Registers regs; char state; };

context fils[N]; int vilki[N]; int curfil = -1;

unsigned int old_SP; int Quit = 0;

void interrupt (*oldvect )(...); void interrupt NewTimer(...); void filosof(); void prtstatus();

void main() { for (int i = 0; i < N; i++) { fils[i].SP = FP_OFF( &fils[i].regs.BP ); fils[i].regs.IP = FP_OFF(filosof); fils[i].regs.CS = _CS; fils[i].regs.DS = _DS; fils[i].regs.ES = _ES; fils[i].regs.FLAGS = _FLAGS; vilki[i] = 0; fils[i].state = 0; } oldvect = getvect(0x8); setvect(0x8, NewTimer); while(Quit != 1); setvect(0x8, oldvect); getchar(); }

void interrupt NewTimer(...) { disable(); oldvect(); if (kbhit()) Quit = 1;

if (curfil<0) old_SP = _SP; else fils[curfil].SP = _SP;

if (curfil+1 >= N) curfil = 0; else curfil+=1;

prtstatus(); if (Quit) _SP = old_SP; else _SP = fils[curfil].SP; enable(); }

void filosof() { int f1, f2; if (curfil == 0) { f1 = N - 1; f2 = 0; } else { f1 = curfil -1; f2 = curfil; }

while(1) { if (vilki[f1]==0 && vilki[f2]==0) { //delay(random(sDELAY)); vilki[f1] = 1; vilki[f2] = 1; fils[curfil].state = 2; delay(random(sDELAY)); vilki[f1] = 0; vilki[f2] = 0; fils[curfil].state = 1; delay(random(sDELAY)); } else { fils[curfil].state = 0; delay(random(lDELAY)); } }

}

void prtstatus() { int i; printf("*****************************************\n"); for (i=0; i<N; i++) printf("filosof #%d : %d \n",i,fils[i].state); for (i=0; i<N; i++) printf("vilka #%d : %d \n",i,vilki[i]); printf("*****************************************\n"); }

http://pastebin.com/7A68WDwA

1) для чего нужен unsigned int bloat[1000];
2) и что именно он в себе хранит и как туда что-то кладется
3) как именно происходит аппаратное прерывание

#356701

volatile int Quit = 0;
В противном случае оптимизатор вправе считать цикл вечным, поскольку в теле цикла переменная не изменяется. Что-то еще вызывает сомнение?

#356703

Да цикл вечный это я в курсе при нажатии любой клавиш он останавливается
вот тут:

text
if (kbhit())
   Quit = 1;

а мне нужно пояснение именно зачем и почему нужен unsigned int bloat[1000];
без него программа не работает а если указать unsigned int bloat[100]; то программа виснит

#356706

Если правильно путаю, то это место под стек псевдопроцессов.

Аппаратное прерывание 08 происходит "само по себе" -- по сигналу от таймера -- каждые 55мс или 18.2 раз в секунду вызывается код, на который указывает вектор 8 таблицы прерываний.

#356707

так вот именно как он туда кладет что-то ? (unsigned int bloat[1000];)
в это массив ну или где можно почитать про эту магию выделение массива под стек

и что еще именно тут происходит

text

        fils[i].SP = FP_OFF( &fils[i].regs.BP );
        fils[i].regs.IP = FP_OFF(filosof);
#356712

Два присваивания. Будущим регистрам SP (указатель стека) и IP (указатель инструкций). Пожалуй, вам нужно почитать про работу процессоров x86 в реальном режиме, если нужно разобраться с заданными вопросами. А насколько это актуально -- решать вам.

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