Там есть leave, это если через ht

через дизасемблер eclipse, ht некоректно дизассемблировал пролог
Код:
switch_task:
002034e8: push %ebp
002034e9: mov %esp,%ebp
002034eb: sub $0x18,%esp
89 if (multi_task)
002034ee: mov 0x205070,%eax
002034f3: test %eax,%eax
002034f5: je 0x20355d <switch_task+117>
92 asm volatile ("pushf; cli");
002034f7: pushf
002034f8: cli
95 asm volatile ("mov %%esp, %0":"=a"(current_thread->esp));
002034f9: mov 0x205dcc,%edx
002034ff: mov %esp,%eax
00203501: mov %eax,0x1c(%edx)
100 current_thread = (thread_t*) current_thread->list_item.next;
00203504: mov 0x205dcc,%eax
00203509: mov 0x4(%eax),%eax
0020350c: mov %eax,0x205dcc
101 current_proc = (process_t*) current_proc->list_item.next;
00203511: mov 0x205ddc,%eax
00203516: mov 0x4(%eax),%eax
00203519: mov %eax,0x205ddc
103 } while ( (current_thread->suspend) || (current_proc->suspend) );
0020351e: mov 0x205dcc,%eax
00203523: mov 0x10(%eax),%eax
00203526: test %eax,%eax
00203528: jne 0x203504 <switch_task+28>
0020352a: mov 0x205ddc,%eax
0020352f: mov 0x14(%eax),%eax
00203532: test %eax,%eax
00203534: jne 0x203504 <switch_task+28>
108 asm volatile ("mov %0, %%esp"::"a"(current_thread->esp));
00203536: mov 0x205dcc,%eax
0020353b: mov 0x1c(%eax),%eax
0020353e: mov %eax,%esp
110 set_kernel_stack_in_tss((u32int) current_thread->stack + current_thread->stack_size);
00203540: mov 0x205dcc,%eax
00203545: mov 0x18(%eax),%eax
00203548: mov %eax,%edx
0020354a: mov 0x205dcc,%eax
0020354f: mov 0x14(%eax),%eax
00203552: add %edx,%eax
00203554: mov %eax,(%esp)
00203557: call 0x20132a <set_kernel_stack_in_tss>
113 asm volatile ("popf");
0020355c: popf
115 }
0020355d: leave
0020355e: ret
P.S.: Дописываю этот пост. Картинки мелкие делаю - превью, чтобы модеры не ругались
Вобщем переписал я на чистом асме переключалку. Исключение #TS исчезло, на скрине вывожу значение tss.esp0 из трех потоков, оно модифицируется переключалкой

Код переключалки на асме
Код:
/*-----------------------------------------------------------------------------
/ Switch task
/----------------------------------------------------------------------------*/
.extern current_thread
.extern tss
.global task_switch
task_switch:
push %ebp
pushf
cli
/* Save current task's ESP */
mov current_thread, %edx
mov %esp, 28(%edx)
/* Get next task */
mov 4(%edx), %ecx
mov %ecx, current_thread
/* Set new ESP */
mov current_thread, %edx
mov 28(%edx), %esp
/* Set TSS kernel stack */
mov 24(%edx), %eax
add 20(%edx), %eax
mov $tss, %edx
mov %eax, 4(%edx)
popf
pop %ebp
ret
Оставил push ebp/pop ebp в прологе/эпилоге для совместимости, хотя теперь можно и без них. Что же делал leave такого пакостного? У Зубкова
Цитата:
Команда выполняет действия, противоположные команде ENTER. Фактически LEAVE только копирует EBP в ESP, тем самым выбрасывая из стекавесь кадр, созданный последней выполненной командой ENTER, и считывает из стека EBP для предыдущей процедуры, что одновременно восстанавливает и значение которое имел ESP до вызова последней команды ENTER
Ну а команда ENTER создает стековый кадр заданного размера и уровня вложенности. Обе команды появились в 80186
Чем опасно использование EBP указателя и как оно инициирует #TS?
P.P.S.: Это одна из немногих функций на асме полностью написанная мной самостоятельно, да ещё и для интеграции в код на C... Аж даже рад что этот косяк вылез
