Модераторы: Poseidon
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> [Assembler]Вывести сообщения, Вывести 2-3 сообщения параллельно 
V
    Опции темы
Гениальный123Робот
Дата 6.5.2007, 09:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 257
Регистрация: 2.1.2006

Репутация: нет
Всего: нет



Написать программу, реализующую мультизадачность в защищенном режиме. Программа должна переключить процессор в защищенный режим, а затем запустить на выполнение 2-3 задачи, которые должны выполняться параллельно. Каждая задача выводит на экран свое сообщение. Задача выводит на экран часть сообщения, затем происходит переключение на другую задачу и т.д. Когда все задачи отработают, программа должна вернуть процессор в реальный режим.

Вообщем, во многом похоже на предыдущую задачу с выводом сообщения в безопасном режиме ;)
Спасибо заранее
PM MAIL   Вверх
dumb
Дата 7.5.2007, 04:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


sceloglauxalbifacies
****


Профиль
Группа: Экс. модератор
Сообщений: 2929
Регистрация: 16.6.2006

Репутация: 6
Всего: 158



Гениальный123Робот, а слабо в книге Зубкова(ссылку на которую я тебе давал) посмотреть пример pm4.asm?
PM MAIL   Вверх
Гениальный123Робот
Дата 7.5.2007, 14:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 257
Регистрация: 2.1.2006

Репутация: нет
Всего: нет



Цитата(dumb @ 7.5.2007,  04:02)
Гениальный123Робот, а слабо в книге Зубкова(ссылку на которую я тебе давал) посмотреть пример pm4.asm?

Чел, ну ты просто супер! Спасибо большое! так к месту твоя книга оказалась!!! ... нет слов, как повезло ;)


Это сообщение отредактировал(а) Гениальный123Робот - 24.6.2008, 10:51
PM MAIL   Вверх
Гениальный123Робот
Дата 24.6.2008, 10:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 257
Регистрация: 2.1.2006

Репутация: нет
Всего: нет



dumb, пришло время для этой темы. Пример взят из Зубкова, глава 10.8.2.  


Сам этот код не компилируется (ошибки). Наверное, я не все сделал. Там в книге после задачи дописано: Чтобы реализовать многозадачность в реальном времени в нашем примере, достаточно создать обработчик прерывания системного таймера IRQ0 в виде отдельной (третьей) задачи и поместить в IDT шлюз этой задачи. Я не совсем понимаю, что это значит. Поясните, плиз.

Спасибо заранее!


Код

; pm4.asm
; Пример программы, выполняющей переключение задач.
; Запускает две задачи, передающие управление друг другу 80 раз, задачи выводят
; на экран символы ASCII с небольшой задержкой
;
; Компиляция:
; TASM:
;   tasm /m pm4.asm
;   tlink /x /3 pm4.obj
; WASM:
;   wasm pm4.asm
;   wlink file pm4.obj form DOS
; MASM:
;   ml /c pm4.asm
;   link pm4.obj,,NUL,,,

        .386p
RM_seg segment para public "CODE" use16
        assume cs:RM_seg,ds:PM_seg,ss:stack_seg
start:
; подготовить сегментные регистры
        push       PM_seg
        pop        ds
; проверить, не находимся ли мы уже в РМ
        mov        eax,cr0
        test       al,1
        jz         no_V86
; сообщить и выйти
        mov        dx,offset v86_msg
err_exit:
        push       cs
        pop        ds
        mov        ah,9
        int        21h
        mov        ah,4Ch
        int        21h

; убедиться, что мы не под Windows
no_V86:
        mov        ax,1600h
        int        2Fh
        test       al,al
        jz         no_windows
; сообщить и выйти
        mov        dx,offset win_msg
        jmp        short err_exit

; сообщения об ошибках при старте
v86_msg db    "Процессор в режиме V86 - нельзя переключиться в РМ$"
win_msg db    "Программа запущена под Windows - нельзя перейти в кольцо 0$"

; итак, мы точно находимся в реальном режиме
no_windows:
; очистить экран
        mov        ax,3
        int        10h
; вычислить базы для всех дескрипторов сегментов данных
        xor        еах,еах
        mov        ax,RM_seg
        shl        eax,4
        mov        word ptr GDT_16bitCS+2,ax
        shr        eax,16
        mov        byte ptr GDT_16bitCS+4,al
        mov        ax,PM_seg
        shl        eax,4
        mov        word ptr GDT_32bitCS+2,ax
        mov        word ptr GDT_32bitSS+2,ax
        shr        eax,16
        mov        byte ptr GDT_32bitCS+4,al
        mov        byte ptr GDT_32bitSS+4,al
; вычислить линейный адрес GDT
        xor        eax,eax
        mov        ax,PM_seg
        shl        eax,4
        push       eax
        add        eax,offset GDT
        mov        dword ptr gdtr+2,eax
; загрузить GDT
        lgdt       fword ptr gdtr
; вычислить линейные адреса сегментов TSS наших двух задач
        pop        eax
        push       eax
        add        eax,offset TSS_0
        mov        word ptr GDT_TSS0+2,ax
        shr        eax,16
        mov        byte ptr GDT_TSS0+4,al
        pop        eax
        add        eax,offset TSS_1
        mov        word ptr GDT_TSS1+2,ax
        shr        eax,16
        mov        byte ptr GDT_TSS1+4,al
; открыть А20
        mov        al,2
        out        92h,al
; запретить прерывания
        cli
; запретить NMI
        in         al,70h
        or         al,80h
        out        70h,al
; переключиться    в РМ
        mov        eax,cr0
        or         al,1
        mov        cr0,eax
; загрузить CS
        db         66h
        db         0EAh
        dd         offset PM_entry
        dw         SEL_32bitCS

RM_return:
; переключиться    в реальный режим RM
        mov        eax,cr0
        and        al,0FEh
        mov        cr0,eax
; сбросить очередь предвыборки и загрузить CS
        db         0EAh
        dw         $+4
        dw         RM_seg
; настроить сегментные регистры для реального режима
        mov        ax,PM_seg
        mov        ds,ax
        mov        es,ax
        mov        ax,stack_seg
        mov        bx,stack_l
        mov        ss,ax
        mov        sp,bx
; разрешить NMI
        in         al,70h
        and        al,07FH
        out        70h,al
; разрешить прерывания
        sti
; завершить программу
        mov        ah,4Ch
        int        21h
RM_seg  ends

PM_seg segment para public "CODE" use32
        assume cs:PM_seg

; таблица глобальных дескрипторов
GDT       label    byte
                   db    8 dup(0)
GDT_flatDS         db    0FFh,0FFh,0,0,0,10010010b,11001111b,0
GDT_16bitCS        db    0FFh,0FFh,0,0,0,10011010b,0,0
GDT_32bitCS        db    0FFh,0FFh,0,0,0,10011010b,11001111b,0
GDT_32bitSS        db    0FFh,0FFh,0,0,0,10010010b,11001111b,0
; сегмент TSS задачи 0 (32-битный свободный TSS)
GDT_TSS0           db    067h,0,0,0,0,10001001b,01000000b,0
; сегмент TSS задачи 1 (32-битный свободный TSS)
GDT_TSS1           db    067h,0,0,0,0,10001001b,01000000b,0
gdt_size = $ - GDT
gdtr               dw    gdt_size-1    ; размер GDT
                   dd    ?             ; адрес GDT
; используемые селекторы
SEL_flatDS         equ   001000b
SEL_16bitCS        equ   010000b
SEL_32bitCS        equ   011000b
SEL_32bitSS        equ   100000b
SEL_TSS0           equ   101000b
SEL_TSS1           equ   110000b

; сегмент TSS_0 будет инициализирован, как только мы выполним переключение
; из нашей основной задачи. Конечно, если бы мы собирались использовать
; несколько уровней привилегий, то нужно было бы инициализировать стеки
TSS_0              db    68h dup(0)
; сегмент TSS_1. В него будет выполняться переключение, так что надо
; инициализировать все, что может потребоваться:
TSS_1              dd    0,0,0,0,0,0,0,0                ; связь, стеки, CR3
                   dd    offset task_1                  ; EIP
; регистры общего назначения
                   dd    0,0,0,0,0,stack_l2,0,0,0B8140h ; (ESP и EDI)
; сегментные регистры
                   dd    SEL_flatDS,SEL_32bitCS,SEL_32bitSS,SEL_flatDS,0,0
                   dd    0                              ; LDTR
                   dd    0                              ; адрес таблицы ввода-вывода

; точка входа в 32-битный защищенный режим
PM_entry:
; подготовить регистры
        xor        еах,еах
        mov        ax,SEL_flatDS
        mov        ds,ax
        mov        es,ax
        mov        ax,SEL_32bitSS
        mov        ebx,stack_l
        mov        ss,ax
        mov        esp,ebx
; загрузить TSS задачи 0 в регистр TR
        mov        ax,SEL_TSS0
        ltr        ax
; только теперь наша программа выполнила все требования к переходу
; в защищенный режим
        xor        еах,еах
        mov        edi,0B8000h          ; DS:EDI - адрес начала экрана
task_0:
        mov        byte ptr ds:[edi],al ; вывести символ AL на экран
; дальний переход на TSS задачи 1
        db         0EAh
        dd         0
        dw         SEL_TSS1
        add        edi,2                ; DS:EDI - адрес следующего символа
        inc        al                   ; AL - код следующего символа,
        cmp        al,80                ; если это 80,
        jb         task_0               ; выйти из цикла
; дальний переход на процедуру выхода в реальный режим
        db         0EAh
        dd         offset RM_return
        dw         SEL_16bitCS

; задача 1
task_1:
        mov        byte ptr ds:[edi],al ; вывести символ на экран
        inc        al                   ; увеличить код символа
        add        edi,2                ; увеличить адрес символа
; переключиться на задачу 0
        db         0EAh
        dd         0
        dw         SEL_TSS0
; сюда будет приходить управление, когда задача 0 начнет выполнять переход
; на задачу 1 во всех случаях, кроме первого
        mov        ecx,02000000h        ; небольшая пауза, зависящая от скорости
        loop       $                    ; процессора
        jmp        task_1

PM_seg  ends

stack_seg segment para stack "STACK"
stack_start        db    100h dup(?)    ; стек задачи 0
stack_l = $ - stack_start
stack_task2        db    100h dup(?)    ; стек задачи 1
stack_l2 = $ - stack_start
stack_seg ends

        end        start


PM MAIL   Вверх
Гениальный123Робот
Дата 27.6.2008, 21:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 257
Регистрация: 2.1.2006

Репутация: нет
Всего: нет



Забыл сказать, что прикрутить (см. предыдущее сообщение) надо вот этот код. Блин, в понедельник надо эту последнюю третью лабу как-то представить в работоспособном виде. Помогите, пожалуйста! 

Код

task_3:   ; при инициализации DS должен быть установлен на PM_seg
        mov        al,20h
        out        20h,al
        mov        word ptr TSS_3,SEL_TSS0
        iret
        mov        al,20h
        out        20h,al
        mov        word ptr TSS_3,SEL_TSS1
        iret
        jmp        task_3


PM MAIL   Вверх
Гениальный123Робот
Дата 29.6.2008, 22:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 257
Регистрация: 2.1.2006

Репутация: нет
Всего: нет



блин, завтра сдавать. а 12 (кроме синтаксич., которые подсветка показывает) одинаковых ошибок Forward reference needs override
никто не знает, что это и как избавиться от нее?  smile 

PM MAIL   Вверх
Гениальный123Робот
Дата 30.6.2008, 17:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 257
Регистрация: 2.1.2006

Репутация: нет
Всего: нет



всё. вопрос снят =) всем спасибо.
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Центр помощи"

ВНИМАНИЕ! Прежде чем создавать темы, или писать сообщения в данный раздел, ознакомьтесь, пожалуйста, с Правилами форума и конкретно этого раздела.
Несоблюдение правил может повлечь за собой самые строгие меры от закрытия/удаления темы до бана пользователя!


  • Название темы должно отражать её суть! (Не следует добавлять туда слова "помогите", "срочно" и т.п.)
  • При создании темы, первым делом в квадратных скобках укажите область, из которой исходит вопрос (язык, дисциплина, диплом). Пример: [C++].
  • В названии темы не нужно указывать происхождение задачи (например "школьная задача", "задача из учебника" и т.п.), не нужно указывать ее сложность ("простая задача", "легкий вопрос" и т.п.). Все это можно писать в тексте самой задачи.
  • Если Вы ошиблись при вводе названия темы, отправьте письмо любому из модераторов раздела (через личные сообщения или report).
  • Для подсветки кода пользуйтесь тегами [code][/code] (выделяйте код и нажимаете на кнопку "Код"). Не забывайте выбирать при этом соответствующий язык.
  • Помните: один топик - один вопрос!
  • В данном разделе запрещено поднимать темы, т.е. при отсутствии ответов на Ваш вопрос добавлять новые ответы к теме, тем самым поднимая тему на верх списка.
  • Если вы хотите, чтобы вашу проблему решили при помощи определенного алгоритма, то не забудьте описать его!
  • Если вопрос решён, то воспользуйтесь ссылкой "Пометить как решённый", которая находится под кнопками создания темы или специальным флажком при ответе.

Более подробно с правилами данного раздела Вы можете ознакомится в этой теме.

Если Вам помогли и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, Poseidon, Rodman

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Центр помощи | Следующая тема »


 




[ Время генерации скрипта: 0.0772 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.