Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Простейшее использование видеопамяти

1.2K
31 июля 2006 года
piroman17
175 / / 20.07.2006
Задача такая: в PM (адресатция сегментная), надо вывести строчку на экран. Вроде задача простая, но ничего не получается.:eek:
Так же я смотрел здесь, почему то тоже строку не выводит. (У меня сделано аналогично).
ПОМОГИТЕ! ВЧЁМ ОШИБКА ИСХОДНОГО КОДА.?
Страницы:
245
31 июля 2006 года
~ArchimeD~
1.4K / / 24.07.2006
Честно говоря не знаю, че там за ошибка но по адресу 0xb8000 все нормально можно записать в видеопамять (textmode). 0xb8000 - начало видеопамяти, адрес на экране вычисляется по формуле:
0xb8000+(y*160)+x*2
у меня все работает
1.2K
31 июля 2006 года
piroman17
175 / / 20.07.2006
[QUOTE=~ArchimeD~]Честно говоря не знаю, че там за ошибка...[/QUOTE]

Ошибка оказалась не в выводе строки, а ещё перед очисткой экрана.
VMware ругается на стек. Это мой Boot-сектор глючит.
1.2K
01 августа 2006 года
piroman17
175 / / 20.07.2006
Оказалось не BootSector:eek:
Проц делает RESET на строке
 
Код:
; собственно, загрузка регистра GDTR:
lgdt    fword ptr GDTR


переменая GDTR:

 
Код:
GDTR    dw    GDT_size-1      ; 16-битнvй лимит GDT
           dd    ?               ; здесь будет 32-битнvй линейнvй адрес GDT


Интересно почему RESET?
349
01 августа 2006 года
Phantom-84
656 / / 27.10.2005
Так процессор реагирует на критические ошибки...
1.2K
01 августа 2006 года
piroman17
175 / / 20.07.2006
[QUOTE=Phantom-84]Так процессор реагирует на критические ошибки...[/QUOTE]

Это понятно, хотел бы я знать в чём она...

Виртуальная машина ругается на стек
(*** Virtual machine kernel stack fault (hardware reset) ***
The virtual machine just suffered a stack fault in kernel mode. On a real computer, ...)

, стек инициалозирую вот так:

 
Код:
mov ax,3000h
mov ss,ax


Может чего в инициализатции поправить:confused:
1.2K
01 августа 2006 года
piroman17
175 / / 20.07.2006
Вот сегмент кода в котором ошобка:

Код:
RM_CODE   segment   para public 'CODE' use16
@@start:
    assume     CS:RM_CODE,SS:RM_STACK
mov ax,3000h
mov ss,ax

; очистка экрана:
                mov             AX,3
                int             10h

; для 32-х битной адресации:
    in    AL,92h
    or    AL,2
    out    92h,AL

; вvчисляем линейнvй адрес метки ENTRY_POINT (точка входа в защищеннvй режим):
    xor    EAX,EAX        ; обнуляем регистра EAX
    mov    AX,PM_CODE      ; AX = номер сегмента PM_CODE
    shl    EAX,4        ; EAX = линейнvй адрес PM_CODE
    add    EAX,offset ENTRY_POINT     ; EAX = линейнvй адрес ENTRY_POINT
    mov    dword ptr ENTRY_OFF,EAX    ; сохраняем его в переменной

; теперь надо вvчислить линейнvй адрес GDT (для загрузки регистра GDTR):
    xor    EAX,EAX
    mov    AX,RM_CODE      ; AX = номер сегмента RM_CODE
    shl    EAX,4        ; EAX = линейнvй адрес RM_CODE
    add    AX,offset GDT      ; теперь EAX = линейнvй адрес GDT

; линейнvй адрес GDT кладем в заранее подготовленнуі переменнуі:
    mov    dword ptr GDTR+2,EAX

; собственно, загрузка регистра GDTR:
   lgdt    fword ptr GDTR                ;ЗДЕСЬ БАГ!!!

; запрет маскируемvх прерvваний:
    cli

; запрет немаскируемvх прерvваний:
    in    AL,70h
    or    AL,80h
    out    70h,AL

; переключение в защищеннvй режим:
    mov    EAX,CR0
    or    AL,1
    mov    CR0,EAX

; загрузить новvй селектор в регистр CS
    db    66h        ; префикс изменения разрядности операнда
    db    0EAh        ; опкод командv JMP FAR
ENTRY_OFF   dd    ?        ; 32-битное смеение
    dw    00001000b      ; селектор первого дескриптора (CODE_descr)

GDT:
; нулевой дескриптор (обязательно должен присутствовать в GDT!):
NULL_descr  db    8 dup(0)
CODE_descr  db    0FFh,0FFh,00h,00h,00h,10011010b,11001111b,00h
DATA_descr  db    0FFh,0FFh,00h,00h,00h,10010010b,11001111b,00h
VIDEO_descr     db              0FFh,0FFh,00h,80h,0Bh,10010010b,01000000b,00h
GDT_size  equ     $-GDT        ; размер GDT


GDTR    dw    GDT_size-1      ; 16-битнvй лимит GDT
        dd    ?               ; здесь будет 32-битнvй линейнvй адрес GDT
RM_CODE         ends

...
349
01 августа 2006 года
Phantom-84
656 / / 27.10.2005
А почему ты в реальном режиме в ss помещаешь именно 3000h? Ты уверен, что настроенный таким образом стек не будет пересекаться с образом программы в памяти? Потом, ты не показал, как инициализируется стек в защищенном режиме...
1.2K
01 августа 2006 года
piroman17
175 / / 20.07.2006
Пересекатся с программами он не будет, в этом я уверен на все 100%.

Да ошибка не в самой LGTD а где то дальше:

А вот и все остальные сегменты:
Код:
; ---------------------------------------------------------------------------------------------------------
PM_CODE   segment   para public 'CODE' use32
    assume  CS:PM_CODE, DS:PM_DATA
ENTRY_POINT:
; загрузим сегментнvе регистрv селекторами на соответствуіие дескрипторv:
          mov         AX,00010000b                ; селектор на второй дескриптор (DATA_descr)
          mov         DS,AX                       ; в DS его
          mov         AX,00011000b                ; селектор на третий дескриптор (VIDEO_descr)
          mov         ES,AX                       ; а этого в ES

          xor            ESI,ESI                     ; обнуляем ESI
          mov            SI,PM_DATA                  ; SI = номер сегмента PM_DATA
          shl            ESI,4                       ; ESI = линейнvй адрес сегмента PM_DATA
          add         ESI,offset message          ; ESI = линейнvй адрес строки message
                xor            EDI,EDI                     ; EDI = позиция на экране (относительно 0B8000h)
          mov         ECX,mes_len                 ; длина текста в ECX

; вvвод на экран:
          rep            movsb                       ; DS:ESI (наше сообение) -> ES:EDI (видеопамять)
          jmp            $                           ; погружаемся в вечнvй цикл
PM_CODE          ends
; ---------------------------------------------------------------------------------------------------------



; T++і+=T -L==-- (для Protected Mode)
; ---------------------------------------------------------------------------------------------------------
PM_DATA          segment        para public 'DATA' use32
    assume         CS:PM_DATA

; сообение, которое мv будем вvводить на экран (оформим его в виде блока повторений irpc):
message:
irpc            mes,           <Congratulations! We are in PM! Now you MUST Press RESET...                >
                db             '&mes&',0Dh
endm
mes_len         equ            $-message       ; длина в байтах
PM_DATA         ends
; ---------------------------------------------------------------------------------------------------------


Кстати сделать стек в защищёном режиме я забыл:(
349
02 августа 2006 года
Phantom-84
656 / / 27.10.2005
Молодец! У него эмулятор ругается из-за стека, а он его просто "забыл сделать" :)
1.2K
02 августа 2006 года
piroman17
175 / / 20.07.2006
[QUOTE=Phantom-84] "забыл сделать" :)[/QUOTE]

Но ведь я как видно из кода нигде после перехода в PM стек не использую!

=============================================

Ну добавил я стек для PM:

 
Код:
stack_Descr db    11111111b,11111111b,00000000b,00001000b,01001000b,10010001b,11001111b,00000000b
          ...

          mov         ax,00100000b
          mov         ss,ax


Всё равно *** Virtual machine kernel stack fault (hardware reset) ***
В этом и есть странность.
349
03 августа 2006 года
Phantom-84
656 / / 27.10.2005
Понимаешь, чтобы стек не использовался вообще, нужно работать с запрещенными прерываниями... Более того, если у тебя произойдет какая-то ошибка, то и исключение не сможет нормально отработать, в следствие чего ты получишь hardware reset...
349
03 августа 2006 года
Phantom-84
656 / / 27.10.2005
А каким значением ты esp инициализируешь, а то обычно стек размещают в конце сегмента, а у тебя при максимальном лимите ненулевая база почему-то...
1.2K
03 августа 2006 года
piroman17
175 / / 20.07.2006
[QUOTE=Phantom-84]А каким значением ты esp инициализируешь, а то обычно стек размещают в конце сегмента, а у тебя при максимальном лимите ненулевая база почему-то...[/QUOTE]

Почему она нулевая то? (выделенно красным)

 
Код:
stack_Descr db    11111111b,11111111b,[COLOR="Red"]00000000b[/COLOR],[COLOR="red"]00001000b[/COLOR],[COLOR="red"]01001000b[/COLOR],10010001b,11001111b,[COLOR="red"]00000000b[/COLOR]


[COLOR="Black"]esp=FFF0h[/COLOR]

Да и ещё RESET происходит на этих строках:
 
Код:
mov         ax,[селектор]
mov         [сег.рег.],ax



Притом независимо что за [селектор] и [сег.регистр] там указать.
334
03 августа 2006 года
HexEdit
809 / / 27.07.2006
[QUOTE=piroman17]Почему она нулевая то? (выделенно красным)

 
Код:
stack_Descr db    11111111b,11111111b,[COLOR="Red"]00000000b[/COLOR],[COLOR="red"]00001000b[/COLOR],[COLOR="red"]01001000b[/COLOR],10010001b,11001111b,[COLOR="red"]00000000b[/COLOR]


[COLOR="Black"]esp=FFF0h[/COLOR]

[/QUOTE]

У тебя в байте флагов сегмента задан атрибут A но не задан W (разрешение записи), и еще стеку задается атрибут обратной адресации.
Вообще для стека байт флагов должен быть примерно таким (красный):
 
Код:
stack_Descr db    11111111b,11111111b,00000000b,00001000b,01001000b,[COLOR=red]10010110b[/COLOR],11001111b,00000000b

Может в этом проблема?
1.2K
03 августа 2006 года
piroman17
175 / / 20.07.2006
Вот я исправил ошибки каторые вы мне рекомендовали исправить:

Код:
.386p

desc_struc struc
 limit  dw 00h  ;15-0 of limit ;0-1
 Base1  dw 00h  ;15-0 of base  ;2-3
 Base2  db 00h  ;23-16 of base ;4
 Opt1   db 00000000b           ;5    
 opt2   db 00000000b           ;6      
 Base3  db 00h  ;31-24 of base ;7
desc_struc ENDS


RM_CODE   segment   para public 'CODE' use16
assume CS:RM_CODE, DS:rM_CODE
Begin:
;Временный стек
mov ax,3000h
mov ss,ax

mov ah,00h
mov al,03h
int 10h      ;очистим экран

;открыть линию А20
in AL,92h
or AL,2
out 92h,AL

;расчёт начала GDT
xor eax,eax
mov AX,RM_CODE      ; AX = номер сегмента GDT
shl EAX,4        ; теперь EAX = линейнvй адрес GDT
add ax,offset GDT_BEGIN
mov dword ptr RM_CODE_Base_lo,eax


;Расчёт базы стека
xor eax,eax
mov ax,PM_STACK
shl eax,4
mov dword ptr TmpBase24_31,eax

;занесём базу стека в дескриптор:
;mov bx,OFFSET GDT_2
mov ax,word ptr TmpBase0_15
mov word ptr GDT_2.Base1,ax
mov al,byte ptr TmpBase16_23
mov byte ptr GDT_2.Base2,al
mov al,byte ptr TmpBase24_31
mov byte ptr GDT_2.Base3,al

;засунем Gdt в регистр GDTR
lgdt FWORD ptr RM_CODE_gdt_ptr

;отключим прерывания:
CLI
; запрет немаскируемvх прерываний:
in AL,70h
or AL,80h
out 70h,AL

;Посидим надорожку:) Поехали!
mov ax, 1
lmsw ax

mov esp,FFF0h
mov ax,0000000000010000b
[COLOR="Blue"]mov ss,ax ;ВОТ ЗДЕСЬ И ПРОИСХОДИТ RESET с гомким матом VMware (*** Virtual machine kernel stack fault (hardware reset) ***)[/COLOR]

sbs:
jmp sbs

GDT_BEGIN  = $ ; отмечаем начало GDT
LABEL   gdtadr          WORD

Gdt_0 db 8 dup (00h)
GDT_2 desc_struc <Stack_end-Stack_begin,,,[COLOR="Red"]10010110b[/COLOR],01000000b,> ;Stack

;DATA
RM_CODE_gdt_ptr dw      $-GDT_BEGIN       ; предел таблицы GDT
RM_CODE_base_lo dw      00h               ; младшее слово базового адреса GDT
RM_CODE_base_hi dw      00h               ; старшее слово базового адреса GDT

;TMP:
TmpBase24_31  db 00h
TmpBase16_23  db 00h
TmpBase0_15   dw 00h

RM_CODE   ends


STACK_BEGIN  = $ ; отмечаем начало GDT
PM_STACK       segment          para stack 'STACK' use32
         db          100h dup(?)                     ; 256 байт под стек - это даже много
PM_STACK       ends
Stack_end =$

end Begin


Но всё равно [COLOR="Red"]*** Virtual machine kernel stack fault (hardware reset) ***[/COLOR] на mov ss,ax

Блин, не могу понять (не посчитайте за тупого:) ) в чём же ошибка?
349
03 августа 2006 года
Phantom-84
656 / / 27.10.2005
[QUOTE=piroman17]Почему она нулевая то?[/QUOTE]Я как раз и написал, что она ненулевая!

Не обязательно для стека использовать растущий вниз сегмент, но верно то, что этот сегмент должен допускать запись! piroman17, в твоем случае нет необходимости в установке бита "растущий вниз сегмент", потому что кроме лишних сложностей это ничего не дает. Попробуй снять этот бит... И еще одно: после переключения в PM первым делом рекомендуется устанавливать cs, т.е. делать дальний переход.
334
04 августа 2006 года
HexEdit
809 / / 27.07.2006
Цитата:
после переключения в PM первым делом рекомендуется устанавливать cs, т.е. делать дальний переход



Я бы даже сказал обязательно, это нужно процу чтобы правильно установить базу, размер и атрибуты сегмента кода.

А к чему относится порт 92h?
а то я все по старинке (A20) :(

 
Код:
mov al, 0D1h
        out 64h, al
        mov al, 0DFh
        out 60h, al
349
04 августа 2006 года
Phantom-84
656 / / 27.10.2005
HexEdit, твой способ такой же неуниверсальный, как и использование исключительно порта 92h! Установку линии A20 следует выполнять, последовательно осуществляя три(!!!) разных метода установки и проверяя факт установки после каждой попытки. Подробно объяснять не буду, но интересной статьёй на эту тему могу поделиться...
8.5K
04 августа 2006 года
infernodiablo
73 / / 04.03.2006
[QUOTE=Phantom-84]Я как раз и написал, что она ненулевая!

Не обязательно для стека использовать растущий вниз сегмент, но верно то, что этот сегмент должен допускать запись! piroman17, в твоем случае нет необходимости в установке бита "растущий вниз сегмент", потому что кроме лишних сложностей это ничего не дает. Попробуй снять этот бит... И еще одно: после переключения в PM первым делом рекомендуется устанавливать cs, т.е. делать дальний переход.[/QUOTE]
Конечно со стеком ты прав... но вот интересная мысля (самому проверять неохота) в дескрипторе 20 битный лимит, т.е. в сегменте данных с расширением вниз будет диапазон допустимых адресов от limit +1 до FFFFFFFFh, но как проц трактует этот лимит при грануляции сегмента в байтах??? если напрямую, то что, минимальный размер стека получается FFFFFFFFh - maxLIMIT= FFFFFFh - FFFFFh = FFF00000h = 4 293 918 720 байт??? не хило... или же он же он считает у таких сегментов при грануляции в байтах лимит как число FFF<LIMIT>h? и тогда минимальный размер стека вообще получается ZERO, а максимальный - 1 048 575 байт?
8.5K
04 августа 2006 года
infernodiablo
73 / / 04.03.2006
[QUOTE=piroman17]Вот я исправил ошибки каторые вы мне рекомендовали исправить:

Код:
.386p

desc_struc struc
 limit  dw 00h  ;15-0 of limit ;0-1
 Base1  dw 00h  ;15-0 of base  ;2-3
 Base2  db 00h  ;23-16 of base ;4
 Opt1   db 00000000b           ;5    
 opt2   db 00000000b           ;6      
 Base3  db 00h  ;31-24 of base ;7
desc_struc ENDS


RM_CODE   segment   para public 'CODE' use16
assume CS:RM_CODE, DS:rM_CODE
Begin:
;Временный стек
mov ax,3000h
mov ss,ax

mov ah,00h
mov al,03h
int 10h      ;очистим экран

;открыть линию А20
in AL,92h
or AL,2
out 92h,AL

;расчёт начала GDT
xor eax,eax
mov AX,RM_CODE      ; AX = номер сегмента GDT
shl EAX,4        ; теперь EAX = линейнvй адрес GDT
add ax,offset GDT_BEGIN
mov dword ptr RM_CODE_Base_lo,eax


;Расчёт базы стека
xor eax,eax
mov ax,PM_STACK
shl eax,4
mov dword ptr TmpBase24_31,eax

;занесём базу стека в дескриптор:
;mov bx,OFFSET GDT_2
mov ax,word ptr TmpBase0_15
mov word ptr GDT_2.Base1,ax
mov al,byte ptr TmpBase16_23
mov byte ptr GDT_2.Base2,al
mov al,byte ptr TmpBase24_31
mov byte ptr GDT_2.Base3,al

;засунем Gdt в регистр GDTR
lgdt FWORD ptr RM_CODE_gdt_ptr

;отключим прерывания:
CLI
; запрет немаскируемvх прерываний:
in AL,70h
or AL,80h
out 70h,AL

;Посидим надорожку:) Поехали!
mov ax, 1
lmsw ax

mov esp,FFF0h
mov ax,0000000000010000b
[COLOR="Blue"]mov ss,ax ;ВОТ ЗДЕСЬ И ПРОИСХОДИТ RESET с гомким матом VMware (*** Virtual machine kernel stack fault (hardware reset) ***)[/COLOR]

sbs:
jmp sbs

GDT_BEGIN  = $ ; отмечаем начало GDT
LABEL   gdtadr          WORD

Gdt_0 db 8 dup (00h)
GDT_2 desc_struc <Stack_end-Stack_begin,,,[COLOR="Red"]10010110b[/COLOR],01000000b,> ;Stack

;DATA
RM_CODE_gdt_ptr dw      $-GDT_BEGIN       ; предел таблицы GDT
RM_CODE_base_lo dw      00h               ; младшее слово базового адреса GDT
RM_CODE_base_hi dw      00h               ; старшее слово базового адреса GDT

;TMP:
TmpBase24_31  db 00h
TmpBase16_23  db 00h
TmpBase0_15   dw 00h

RM_CODE   ends


STACK_BEGIN  = $ ; отмечаем начало GDT
PM_STACK       segment          para stack 'STACK' use32
         db          100h dup(?)                     ; 256 байт под стек - это даже много
PM_STACK       ends
Stack_end =$

end Begin


Но всё равно [COLOR="Red"]*** Virtual machine kernel stack fault (hardware reset) ***[/COLOR] на mov ss,ax

Блин, не могу понять (не посчитайте за тупого:) ) в чём же ошибка?[/QUOTE]
Если хотишь использовать в качестве стека сегмент с расширением вниз, то поставь лучше базу, как первый байт следующий за стеком... А то ты стек суешь в запрещенные адреса...
8.5K
05 августа 2006 года
infernodiablo
73 / / 04.03.2006
[QUOTE=HexEdit]У тебя в байте флагов сегмента задан атрибут A но не задан W (разрешение записи), и еще стеку задается атрибут обратной адресации.
Вообще для стека байт флагов должен быть примерно таким (красный):
 
Код:
stack_Descr db    11111111b,11111111b,00000000b,00001000b,01001000b,[COLOR=red]10010110b[/COLOR],11001111b,00000000b

Может в этом проблема?[/QUOTE]
Сколько проблем со стеком... вообще - то с расширением вниз делают токо тогда стек, когда динамически, по мере надобности, хотят его увеличивать... Да и вообще зачем PM? REAL MODE - вот рулез!
8.5K
05 августа 2006 года
infernodiablo
73 / / 04.03.2006
Если тебе это поможет, то моя РАБОЧАЯ переделка твоей проги + немного своего:
;
;
; СИНТАКСИС ДЛЯ FASM %-)
;
;
format MZ
entry main:start
segment main use16
start:

push word gdt_seg ; загрузка в DS сегмента с будущей GDT
pop ds

mov ah,00h
mov al,03h
int 10h ;очистим экран

xor eax,eax
mov ax,gdt_seg
sal eax,4
or dword [base_gdt],eax ; установим базу для дескриптора gdt...
mov dword [base_gdt_reg],eax

xor eax,eax
mov ax,pm_code
sal eax,4
or dword [base_code],eax ; для сегмента кода

xor eax,eax
mov ax,stek
sal eax,4
or dword [base_stek],eax ; для стека

xor eax,eax ; установим базу для сегмента данных
mov ax,pm_data
sal eax,4
or dword [base_data],eax

lgdt pword [gdt_reg] ; загрузим gdtr

cli

mov eax,cr0 ; идем в протект
or eax,1
mov cr0,eax

call far pword 010000b:pm_entry ; дальний переход на входную метку
; ...

segment pm_code use32
code_beg = $
pm_entry:
mov ax,011000b ; установим стек
mov ss,ax
mov esp,stek_size-5
push word 100000b ; установим используемые селекторы (ES - сегмент текст. буфера
pop es ; DS - сегмент данных
push word 101000b
pop ds
mov esi,messeage ; зададим знач. для функции вывода (ds:esi - смещ выводимой строки
mov ecx,12 ; ecx - сколько писать, edi - номер символа выводимой строки)
xor edi,edi
call near dword text
hlt ; остановим работу процессора


text: ; :-)
push ecx
movzx edi,di
and di,0fffeh
movzx ecx,cx
mov ah,017h
.zikl:
mov al,[esi]
es mov word [edi],ax
add edi,2
movzx edi,di
inc esi
loop .zikl
pop ecx
retnd
code_size = code_beg-$


segment pm_data use16
data_beg = $
messeage db 'Hello world!' ; типа здравие желаю...
rd 10
data_size = data_beg-$

segment stek use16
stek_beg = $
rd 100
stek_size = stek_beg-$

segment gdt_seg use16
gdt_beg = $
void_desc dd 0 ; пустой дескриптор
dd 0
gdt_desc dw gdt_size-1 ; дескриптор описывающий GDT, вдруг захош дескр. переписать
base_gdt dw 0
db 0
db 10010010b
dw 0
code_desc dw code_size-1 ; сегмент кода
base_code dw 0
db 0
db 10011010b
dw 01000000b ; будет 32 битный
stek_desc dw stek_size-1 ; стек с расширением вверх
base_stek dw 0
db 0
db 10010010b
dw 0
graf_desc dw 0ffffh ; текстовый буфер
dw 08000h
db 0bh
db 10010010b
dw 0
data_desc dw data_size-1 ; сегмент данных
base_data dw 0
db 0
db 10010010b
dw 0
real_flat_desc dw 0ffffh ; не нужная хрень, но приготиться для возврата в Реал...
dw 0
db 0
db 10010010b
dw 0

gdt_size = gdt_beg - $

gdt_reg dw gdt_size-1 ; псевдодескриптор GDT
base_gdt_reg dd 0
349
05 августа 2006 года
Phantom-84
656 / / 27.10.2005
[QUOTE=infernodiablo]Конечно со стеком ты прав... но вот интересная мысля (самому проверять неохота) в дескрипторе 20 битный лимит, т.е. в сегменте данных с расширением вниз будет диапазон допустимых адресов от limit +1 до FFFFFFFFh, но как проц трактует этот лимит при грануляции сегмента в байтах??? если напрямую, то что, минимальный размер стека получается FFFFFFFFh - maxLIMIT= FFFFFFh - FFFFFh = FFF00000h = 4 293 918 720 байт??? не хило... или же он же он считает у таких сегментов при грануляции в байтах лимит как число FFF<LIMIT>h? и тогда минимальный размер стека вообще получается ZERO, а максимальный - 1 048 575 байт?[/QUOTE]Принцип такой же, просто когда лимит указывается в байтах, размер сегмента не может превышать 64 Кб (не 4 Гб), т.е. вычислять нужно так 0FFFFh - 0FFFFh = 0 (нулевой размер!!!) и 0FFFFh - 0 = 0FFFFh (64 Кб минус 1 байт). Иными словами, расширяемый вниз сегмент не может быть размером 64 Кб (4 Гб), но зато может иметь нулевой размер!
8.5K
05 августа 2006 года
infernodiablo
73 / / 04.03.2006
[QUOTE=Phantom-84]Принцип такой же, просто когда лимит указывается в байтах, размер сегмента не может превышать 64 Кб (не 4 Гб), т.е. вычислять нужно так 0FFFFh - 0FFFFh = 0 (нулевой размер!!!) и 0FFFFh - 0 = 0FFFFh (64 Кб минус 1 байт). Иными словами, расширяемый вниз сегмент не может быть размером 64 Кб (4 Гб), но зато может иметь нулевой размер![/QUOTE]
... Сказки... если бит грануляции снят (т.е. лимит в байтах, а не в страницах), то размер сегмента не может превышать 1 МЕГАБАЙТ (проверено на практике), т.к. поле границы - 20 битное, а не 16 битное... , а 64 кб это на допотопных процах типа 286
P.S. это я про дескрипторы начиная с 486 где 20 битный лимит, 32 битная база...
349
05 августа 2006 года
Phantom-84
656 / / 27.10.2005
Так я и рассказывал эту сказку, опираясь на принципы совместимости, декларируемые производителями процессоров. Т.е. все, что я сказал, верно для сегментных дескрипторов, бит разрядности которых равен нулю. В противном случае этот вопрос действительно становится интересным - нужно проверять!

P.S. В моей оси значения бита разрядности и бита гранулярности в сегментных дескрипторах всегда совпадают! Дескрипторы с G=B=0 используются лишь при возврате в реальный режим во время парковки системы. В экспериментальных версиях, в которых парковка осуществляется без возврата в реальный режим, используются только сегментные дескрипторы с G=B=1...
8.5K
05 августа 2006 года
infernodiablo
73 / / 04.03.2006
Какую работку я проделал по стеку с расширением вниз... вот исходный текст РАБОТАЮЩЕЙ программы:

;
;
; СИНТАКСИС ДЛЯ FASM %-)
;
;
format MZ
entry main:start
segment main use16
start:

push word gdt_seg ; загрузка в DS сегмента с будущей GDT
pop ds

mov ah,00h
mov al,03h
int 10h ;очистим экран

xor eax,eax
mov ax,gdt_seg
sal eax,4
or dword [base_gdt],eax ; установим базу для дескриптора gdt...
mov dword [base_gdt_reg],eax

xor eax,eax
mov ax,pm_code
sal eax,4
or dword [base_code],eax ; для сегмента кода

xor eax,eax
mov ax,stek
sal eax,4
add eax,stek_size
mov word [base_stek],ax ; установим базу для стека как байт следующий за стеком
shr eax,16
mov byte [stek_desc+4],al
mov byte [stek_desc+7],ah
mov eax,0fffffh ; интерпретируем 20 битную границу
sub eax,stek_size
mov word [stek_desc],ax
shr eax,16
or byte [stek_desc+6],al

xor eax,eax ; установим базу для сегмента данных
mov ax,pm_data
sal eax,4
or dword [base_data],eax

lgdt pword [gdt_reg] ; загрузим gdtr

cli

mov eax,cr0 ; идем в протект
or eax,1
mov cr0,eax

call far pword 010000b:pm_entry ; дальний переход на входную метку
; ...

segment pm_code use32
code_beg = $
pm_entry:
mov ax,011000b ; установим стек
mov ss,ax
mov esp,0fffffff0h
mov ebp,0ffffffffh
sub ebp,stek_size
;ss mov byte [ebp],2 ; если пропуск снять ; , то программа не заработает
push word 100000b ; установим используемые селекторы (ES - сегмент текст. буфера
pop es ; DS - сегмент данных
push word 101000b
pop ds
ss cmp byte [ebp+1],1ah ; если стек не в том сегмете, тогда буква H не сотрется
jne .next
and byte [messeage],0
.next:
mov esi,messeage ; зададим знач. для функции вывода (ds:esi - смещ выводимой строки
mov ecx,12 ; ecx - сколько писать, edi - номер символа выводимой строки)
xor edi,edi
call near dword text
hlt ; остановим работу процессора


text: ; :-)
push eax
push ecx
movzx edi,di
and di,0fffeh
movzx ecx,cx
mov ah,017h
.zikl:
mov al,[esi]
es mov word [edi],ax
add edi,2
movzx edi,di
inc esi
loop .zikl
pop ecx
pop eax
retnd
code_size = code_beg-$


segment pm_data use16
data_beg = $
messeage db 'Hello world!' ; типа здравие желаю...
rd 10
data_size = data_beg-$

segment stek use16
stek_beg = $
db 1ah
rd 1024
stek_size = stek_beg-$

segment gdt_seg use16
gdt_beg = $
void_desc dd 0 ; пустой дескриптор
dd 0
gdt_desc dw gdt_size-1 ; дескриптор описывающий GDT, вдруг захош дескр. переписать
base_gdt dw 0
db 0
db 10010010b
dw 0
code_desc dw code_size-1 ; сегмент кода
base_code dw 0
db 0
db 10011010b
dw 01000000b ; будет 32 битный
stek_desc dw 0 ; стек с расширением вниз
base_stek dw 0
db 0
db 10010110b
dw 0
graf_desc dw 0ffffh ; текстовый буфер
dw 08000h
db 0bh
db 10010010b
dw 0
data_desc dw data_size-1 ; сегмент данных
base_data dw 0
db 0
db 10010010b
dw 0
real_flat_desc dw 0ffffh ; не нужная хрень, но приготиться для возврата в Реал...
dw 0
db 0
db 10010010b
dw 0fh

gdt_size = gdt_beg - $

gdt_reg dw gdt_size-1 ; псевдодескриптор GDT
base_gdt_reg dd 0



Следую предположению что процессор считает допустимыми адресами в сегменте с расширением вниз от FFF<limit> до FFFFFFFFh я установил базу сегмента как первый байт следующий за стеком, соответствующим образом интерпретировал границу. После перехода в защищенный режим регистр ESP устанавливается со значением 0FFFFFFF0h, и устанавливается SS на сегмент стека с расширением вниз. Судя по тому что программа нормально работала (без перезагрузки, происходящей при исключении) делаю вывод, что предположение верно. Чтобы проверить правильно, и втом ли месте создан сегмент стека, я в нем первый байт установил как маркер со значением 1ah, в работе программы если маркер прочитаный по адресу FFF<limit>+1 является установленным маркером, то стирается буква "H" в выводимой строке. Для проверки границы стека установил команду, которая пытается писать по адресу FFF<limit>, при установленной этой команде программа вызывала исключение и перезагружала комп.
ВЫВОД: При работе в защищенном режиме, процессор считает разрешенными адресами (при которых не возникает исключение общей защиты) от FFF<limit>+1 до FFFFFFFFh и следовательно минимальный размер стека с расширением вниз = 0, максимальный = 1 Мб
P.S. Как вы делаете текст программы в окошке с прокруткой?
8.5K
05 августа 2006 года
infernodiablo
73 / / 04.03.2006
[QUOTE=Phantom-84]Так я и рассказывал эту сказку, опираясь на принципы совместимости, декларируемые производителями процессоров. Т.е. все, что я сказал, верно для сегментных дескрипторов, бит разрядности которых равен нулю. В противном случае этот вопрос действительно становится интересным - нужно проверять!

P.S. В моей оси значения бита разрядности и бита гранулярности в сегментных дескрипторах всегда совпадают! Дескрипторы с G=B=0 используются лишь при возврате в реальный режим во время парковки системы. В экспериментальных версиях, в которых парковка осуществляется без возврата в реальный режим, используются только сегментные дескрипторы с G=B=1...[/QUOTE]
Принципы совместимости??? может ты и прав, но я в своей жизни не разу не видел проц. intel 80286 и по моему писать программы совместимые с этими неиспользуемым более 10 лет процессорами нецелесообразно...
349
05 августа 2006 года
Phantom-84
656 / / 27.10.2005
Вполне может быть!!! Только по аналогии с "чистыми" 16- и 32-разрядными сегментами может все-таки 1 Мб минус один байт???

P.S. Используй парный тег code в кв. скобках :)
8.5K
05 августа 2006 года
infernodiablo
73 / / 04.03.2006
[QUOTE=infernodiablo]Принципы совместимости??? может ты и прав, но я в своей жизни не разу не видел проц. intel 80286 и по моему писать программы совместимые с этими неиспользуемым более 10 лет процессорами нецелесообразно...[/QUOTE]
Ты ОС пишешь??? на чем и для какой цели?
8.5K
05 августа 2006 года
infernodiablo
73 / / 04.03.2006
[QUOTE=Phantom-84]Вполне может быть!!! Только по аналогии с "чистыми" 16- и 32-разрядными сегментами может все-таки 1 Мб минус один байт???

P.S. Используй парный тег code в кв. скобках :)[/QUOTE]
Дык это понятно, что сегмент с расширением вниз имеет максимальный размер на 1 байт меньше (или страницу), чем его сородич с расширением вверх
349
05 августа 2006 года
Phantom-84
656 / / 27.10.2005
Это хобби, на ассемблере (fasm)...
8.5K
05 августа 2006 года
infernodiablo
73 / / 04.03.2006
[QUOTE=Phantom-84]Это хобби, на ассемблере (fasm)...[/QUOTE]
Блин... а я уж начал думать что на fasm только я (дурак) один пишу... мне не нравиться в нем что он когда делает программу не выдает листинг в файл... а бывает где -нибудь допустишь ошибку, типа метку забудешь поставить а в команде перехода ее напишешь, то он вообще ошибку не показывает и компилировать отказывается...
349
05 августа 2006 года
Phantom-84
656 / / 27.10.2005
У меня к fasm'у вообще нет никаких претензий. Он мне очень нравится!!! Я даже приложения под винды на нем частенько пишу!
349
05 августа 2006 года
Phantom-84
656 / / 27.10.2005
У тебя какая версия?
8.5K
05 августа 2006 года
infernodiablo
73 / / 04.03.2006
[QUOTE=Phantom-84]У тебя какая версия?[/QUOTE]
version 1.20 если есть новее, то давай мне ссылочку на сайт, где можно его качнуть...
P.S. Мне он тоже нравится, в нем нет лишнего как в tasm и позволяет написать нечто вроде call far dword 123:5678, на что некоторые ассемблеры ругаются... но только вот с макросами я в нем так и не разобрался... пишу без них :-)
334
06 августа 2006 года
HexEdit
809 / / 27.07.2006
FASM качать с http://flatassembler.net/download.php. Актуальная версия сейчас - 1.67.7.
На http://flatassembler.net/ много полезного.

ЗЫ. FASM - RULEZZZ!!!
1.2K
06 августа 2006 года
piroman17
175 / / 20.07.2006
Я кароче сам разобрался с одной половиной ошибок:
 
Код:
[COLOR="Red"]shl eax,4[/COLOR]

Написал в исходном коде Shl eax,3 и думал почему всё глючит!
Кстати тут на форуме (mes#16) я написал Shl eax,4:D

во все сегменты всё пишется КРОМЕ [COLOR="red"]CS[/COLOR]

Может я не верно указал параметры сегмента:confused:

 
Код:
... 10011000b, 00000000b ...
334
06 августа 2006 года
HexEdit
809 / / 27.07.2006
Параметры правильно. А как ты CS илициализируешь?
349
06 августа 2006 года
Phantom-84
656 / / 27.10.2005
1.20 - это очень древняя версия!!! Я три года назад уже пользовался версией 1.44, а сейчас использую 1.64!
1.2K
06 августа 2006 года
piroman17
175 / / 20.07.2006
Это в GDT:
 
Код:
GDT_1 desc_struc <PM_CODE_END-PM_CODE_Begin,,,10011110b,00000000b,>



Это я вычисляю начало PM_CODE:
Код:
;Расчёт базы кода
xor eax,eax
mov ax,cs
shl eax,4
add ax,offset PM_CODE
mov dword ptr TmpBase24_31,eax

;занесём базу кода в дескриптор:
mov al,byte ptr TmpBase0_15
mov byte ptr GDT_1.Base1,al
mov ax,word ptr TmpBase16_23
mov word ptr GDT_1.Base2,ax
mov al,byte ptr TmpBase24_31
mov byte ptr GDT_1.Base3,al



А вот сам инит:

 
Код:
db    66h                ;префикс изменения разрядности операнда
    db    0EAh              ; опкод команды JMP FAR
    dd    00h                ; 32-битное смещение
    dw   00001000b      ; селектор первого дескриптора (CODE_descr)

Мне кажется проц почему то не хочет менять CS:confused: .

Кстати ещё... Написал обработчик прерываний таже проблема: при первом же прерывании RESET:mad:
Сразу говорю обработчик простой: там только "Конец прерывания" и IRET, врятли там есть ошибка.
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог