// v1_zad8.cpp // prevodjenje iz komandne linije: bcc -ms -Ic:\bc31\include -Lc:\bc31\lib v1_zad8.cpp #include #include struct cnt_buf { // pomeraj unsigned sp; // +0 unsigned ax; // +2 unsigned bx; // +4 unsigned cx; // +6 unsigned dx; // +8 unsigned pc; // +10 unsigned bp; // +12 }; struct PCB { cnt_buf* context; unsigned* stack; }; unsigned _setjmp(cnt_buf *b){ asm { push bx mov bx, [bp+4] // BX = b mov bx[2], ax // ax polje pop WORD PTR [bx+4] // bx mov bx[6], cx // cx mov bx[8], dx // dx mov ax, bp[0] // AX = old_bp mov bx[12], ax // bp mov ax, bp[2] // AX = pc_ret mov bx[10], ax // pc mov [bx], sp // running->sp=SP //skida se sa steka b, PC, BP add WORD PTR[bx], 6 } return 0; } void _longjmp(cnt_buf *b, unsigned i){ asm { mov ax, [bp+6] // AX = i mov bx, [bp+4] // BX = b; mov sp, [bx] // restauriramo stek push bx // Vracamo b, push WORD PTR bx[10] // pc, push WORD PTR bx[12] // i bp na stek. mov bp, sp // BP <= SP // mov ax, bx[2] // ne radi se restauracija ax, jer ce to biti povratna vrednost!!! push WORD PTR bx[4] // cuvamo bx polje na steku mov cx, bx[6] // restauracija CX mov dx, bx[8] // restauracija DX pop bx // restauracija BX } } void createThread(PCB *newPCB, void (*body)()) { newPCB->stack = new unsigned[1024]; newPCB->context = new cnt_buf; newPCB->context->pc = FP_OFF(body); newPCB->context->sp = FP_OFF(newPCB->stack+1024); } PCB *p[3]; PCB* running; int nextThread; //makro #define dispatch(x) { \ nextThread = x; \ _dispatch(); \ } void _dispatch(){ if (_setjmp(running->context) == 0) { running = p[nextThread]; _longjmp(running->context,1); } else { return; } } // funkcija koju izvrsava nit 1 void a() { int i; for (i = 0; i < 3; ++i) printf("U a() %d\n",i); asm mov ax, 7 dispatch(2); asm mov i, ax printf(" u a() ax = %d\n",i); for (i = 0; i < 3; ++i) printf("U a() %d\n",i); dispatch(2); } // funkcija koju izvrsava nit 2 void b() { for (int i = 0; i < 3; ++i) printf("U b() %d\n",i); asm mov ax, 2 dispatch(1); for (i = 0; i < 3; ++i) printf("U b() %d\n",i); dispatch(0); } void delete_all() { delete [] p[1]->stack; delete [] p[2]->stack; delete [] p[1]->context; delete [] p[2]->context; delete p[0]; delete p[1]; delete p[2]; } int main() { p[1] = new PCB(); createThread(p[1], a); printf("napravio a\n"); p[2] = new PCB(); createThread(p[2], b); printf("napravio b\n"); p[0] = new PCB(); running = p[0]; dispatch(1); printf("Kraj.\n"); delete_all(); return 0; }