asm {
lea bx,Context
Как реализовать мультизадачность в BorlandC++ ?
Преподаватель объяснял, что для этого как минимум нужно восстановить [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();
}
#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();
}
#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();
}
вопрос в чем?
Но мне вот абсолютно не понятно, как это вообще должно работать. В функции swap меняются местами области в 24 байта по адресам bx и bp. Инициализации bx и bp не видно. Вот как это может работать?
Цитата: P*t*
Вопрос понятно в чем - описано что хотелось и что получилось, ожидается что кто-нибудь объяснит, почему получилось не то.
Но мне вот абсолютно не понятно, как это вообще должно работать. В функции swap меняются местами области в 24 байта по адресам bx и bp. Инициализации bx и bp не видно. Вот как это может работать?
Но мне вот абсолютно не понятно, как это вообще должно работать. В функции 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
}
*(Context+i)=0;
asm {
lea bx,Context
lea dx,pp;
mov [bx+18],dx
mov ax,cs
mov [bx+20],ax
}
Затем, при каждом запуске swap(), bx привязывается к Context
Код:
Угробил полтора месяца на этот пример. Было бы здорово разобраться почему это не работает и сделать рабочий вариант
вам надо при инициализации задачи создать копии сегментов стека и данных , а при прерывании просто менять значения сегментных регистров , предварительно сохранив контекст в текущий стек .