У меня все получилось. Следующий код выводит оба символа (каждый из отдельной задачи):
Код:
...
; создаем потомка
call fork
and eax,eax
jz child
mov word [VFB],32 + 22h shl 8
jmp @f
child:
mov word [VFB+80*2],32 + 44h shl 8
@@:
hlt
jmp @b
Формируя стек для потомка, я просто сделал его на 16 байт глубже (относительно esp родителя) и разместил в этих 16 байтах стековый кадр для корректного выхода из подпрограммы переключения в контексте новой задачи (аналогичный тому, который я использовал
здесь). Адрес запуска новой задачи установил на адрес возврата из insertts внутри fork'а. Кстати можно было вообще установить адрес запуска на "return 0", чтобы избежать лишнего ветвления в конце fork'а:
Код:
...
; вставляем структуру задачи в runqueue
call insertts
start:
pop eax ; адрес созданной структуры задачи
pop ecx ; индекс созданной структуры задачи
sub eax,[current]
jz @f ; child
mov eax,ecx
@@:
ret
Если в Си не захочется использовать метку start, этот адрес можно взять внутри insertts аналогично тому, как это было сделано в read_eip. Вместо pid'а использовал описатель (индекс) задачи, но в данном случае это не существенно, тем более что у первичной задачи описатель равен 0, а у первого потомка – 1.