Всем привет! Задали мне курсовую, тема: "Реализация многопоточности в реальном режиме работы микропроцессора". В АСМе я не силен, и написать такое приложение явно не смогу. Может есть у кого-то такое приложение? Это может быть что-то вроде змеек, но желательно не они. Заранее благодарен.
Цикл: Туториалы Iczelion'а о Win32 API Win32 API. Урок 15. Треды (ветви) http://wasm.ru/article.php?article=1001015 Почитай, все просто. Тем более такой ник себе выбрал.
Читал, для меня это темень, А может есть у кого-то исходник чего-то на подобии змейки? А ник надо заранее забивать, потом не будет
НУ может это ... Код (Text): .386 .model flat, stdcall option casemap:none include \masm32\include\windows.inc include \masm32\include\kernel32.inc include \masm32\include\masm32.inc includelib \masm32\lib\kernel32.lib includelib \masm32\lib\masm32.lib ThreadProc PROTO :DWORD ;----------------------------------- .data hThreadProc dd 0 dwtid dd 0 szMessage_frMain db 13,10,'<> From Main here ...',13,10,0 szMessage_frThread db ' > From Thread here ...',13,10,0 szMessage_prEnter db '[Enter]',13,10,0 input_buffer db 1 dup(0) ;----------------------------------- .code main: invoke StdOut, addr szMessage_frMain invoke CreateThread,NULL,0,addr ThreadProc,NULL,0,addr dwtid mov hThreadProc, eax invoke Sleep, 3000 invoke TerminateThread,hThreadProc,0 invoke CloseHandle,hThreadProc invoke StdOut, addr szMessage_frMain invoke StdOut, addr szMessage_prEnter invoke StdIn, addr input_buffer, 1 invoke ExitProcess,0 ;----------------------------------- ThreadProc PROC hInst:DWORD .while 1 invoke Sleep, 1000 invoke StdOut, addr szMessage_frThread .endw ret ThreadProc ENDP end main ???!!!
SystemX86 читаете про нити и кооперативную многозадачность. исходники берете из какой нибудь простой малоразмерной или учебной оси. желательно, с описанием получше. вас будет интересовать планировщик. даже не знаю что вам посоветовать если вы 0 и желаете 0 оставаться. классика - миникс. видел описания с кусками кода для линя и для плана. неплохо расписан кнх в книгах кёртена. но все это сложно (может, кроме миникса). даже не знаю что сказать.. с таким желанием ничего не знать, может вам покинуть ваш ин? все равно работать по специальности не сможете. будете барыжить если не сможете пролезть бумажки перекладывать. а так, хоть времени не потеряете?
В реальном режиме? Какая винда, она в PM, да про нити уже рассказали. Если писать под RM с 0 то это дело не слишком сложно. Вот открываем интеловский ман, смотрим что такое TSS, так вот. Делаем структуру, наподобие TSS (они в PM), потом разделяем место под адресное пространство задач. При тике таймера сохраняем текущий контекст и переключаемся на следующий. Словами долго описывать.
простейшая реализация кооперативной многозадачности на колене. набросок без каких либо проверок на ошибки (стало быть, они там имеются). но достаточно чтоб уловить идею и, возможно, даже представить как набросок вашему учителю завтра. Код (Text): //////////////////////////////////// // хидер #define TASK_HEAP_SIZE 0x1000 typedef struct { ... } Context; typedef void (*Task)(Context *ctxt); typedef struct { unsigned flags; unsigned ax; unsigned bx; // ...... unsigned sp; unsigned ip; void* stack_base; } Registers; typedef struct { Task task; Context *ctxt; Registers regs; } Fiber; /////////////////////////////////// // очередь задач Fiber queue[] = { {null, null, {0}}, // 0 используется для сохранения стартовых значений {&task1, &ctxt1, {0}}, {&task2, &ctxt2, {0}}, {&task3, &ctxt3, {0}} }; int queue_len = 3; int cur_task = 0; ///////////////////////////////// // задачи //-- 1-вая ----------- Context ctxt1 = { ... }; void task1(Context *ctxt){ ... } //-- 2-рая ---------- Context ctxt2 = { ... }; void task2(Context *ctxt){ ... } //-- 3-тья ---------- Context ctxt3 = { ... }; void task3(Context *ctxt){ ... } ///////////////////////////////////// // служебные функции // выход из программы void exit(){ for(; queue_len > 0; queue_len--){ if(queue[queue_len].regs.stack_base != 0) free(queue[queue_len].regs.stack_base); queue[queue_len].regs.stack_base = 0; } cur_task = -1; queue_len = queue[0].regs.sp; _asm{ push queue_len pop sp jmp shedule } } // вызов stop удаляет текущую нить из планировщика void stop(){ free(queue[cur_task].regs.stack_base); queue[cur_task].regs.stack_base = 0; queue[cur_task].task = 0; shedule(); } Fiber *cur_fiber; Registers *cur_regs; // вызов shedule передает управление следующей нити. void shedule(){ if(cur_task != -1){ cur_fiber = &queue[cur_task]; cur_regs = &cur_fiber->regs; _asm{ pushf push ax ; ... call M jmp Exit } M: _asm{ mov ax,cur_regs pop [ax + Registers.ip] ; ... pop [ax + Registers.ax] pop [ax + Registers.flags] } do{ cur_task++; if(cur_task > queue_len) cur_task = 1; }until(queue[cur_task].task == 0); }else{ cur_task = 0; } cur_fiber = &queue[cur_task]; cur_regs = &cur_fiber->regs; // если очередная нить еще не запускалась - инициализируем ее if(cur_regs->ip == 0) cur_regs->ip = cur_fiber->task; if(cur_regs->sp == 0){ cur_regs->stack_base = malloc(TASK_HEAP_SIZE); cur_regs->sp = (unsigned)cur_regs->stack_base + TASK_HEAP_SIZE - sizeof(void*); *(Context**)cur_regs->sp = cur_fiber->ctxt; cur_regs->sp -= sizeof(void*); *(void**)cur_regs->sp = (void*)&stop; } _asm{ ; эта часть была изменена. ; предыдущая схема восстановления состояния нити ; была неработоспособна mov ax,cur_regs mov sp,[ax + Registers.sp] ; ... mov bx,[ax + Registers.bx] push [ax + Registers.flags] popf push [ax + Registers.ip] mov ax,[ax + Registers.ax] ret } Exit: } int main(){ shedule(); return 0; } вытесняющая многозадачность в самом простейшем случае отличается от кооперативной только тем, что шедулер в ней вызывается принудительно по таймеру (из прерывания таймера). ADD исправил ошибку в схеме восстановления состояния нити. снова ничего не проверял.
NT в протектед моде выполняется. Какие есчо CreateThread() в реалмоде Таймерами рулите, либо делайте как в нт - для всех прерываний общий диспетчер, из него переключайте задачи.