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

Ваш аккаунт

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

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

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

Помогите с загрузчиком

1.8K
29 сентября 2007 года
Evgeni
188 / / 14.06.2006
Пишу простой загрузчик, но столкунулся с такой проблемой, как вывести символы

IDEAL
model tiny

codeseg
start:
xor ax,ax
cli
mov ax,cs
mov ss,ax
mov ds,ax
lea sp,[start]
sti

mov si,offset msg
mov ah,0eh
lodsb ;здесь должны
int 10h ;были вывестись
lodsb ;три символа
int 10h ;
lodsb ;
int 10h ;

cli
hlt

msg:
db 'abs'
end start

но почему он выводит вообще другую инфу
Страницы:
349
16 октября 2007 года
Phantom-84
656 / / 27.10.2005
Короче, объясняю.

Сейчас обычно используется FLAT-модель памяти - это когда все сегменты имеют нулевую базу и размер 4 Гб. В этом случае тебе в начале бинарника нужно указать директиву org 7C00h и, если ты собираешься свой образ загружать в память последовательно (т.е. след. сектор по адресу 7E00h и т.п.), то тебе больше директиву org использовать не нужно, а нужно просто указать во всех дескрипторах сегментов нулевую базу и максимальный лимит, а также страничную гранулярность. В этом случае тебе нужна такая разметка:
Код:
org 7C00h
...
rb 7DFEh-$
dw 0AA55h
...
GDTR:
dw GDT_SIZE-1
dd GDT_BASE

align 8
GDT_BASE:
dq 0
desc 0, 0FFFFFh, DF_CODE or DF_DUALACTION or \
DF_PRESENT or DF_USE32 or DF_PAGED ; для сегмента кода
desc 0, 0FFFFFh, DF_DATA or DF_DUALACTION or \
DF_PRESENT or DF_USE32 or DF_PAGED ; для сегмента данных
GDT_SIZE=$-GDT_BASE

use32
entry32:
...
virtual ; 32-разрядный стек, под который нужно распределить память
align 1000h
rb 4000h
end virtual


Если ты хочешь использовать свой вариант, то лучше все-таки код и данные хранить в одном адресном пространстве, т.е. сделать базы сегмента кода и сегмента данных/стека одинаковыми, чтобы внутрисегментные адреса внутри этого пространства были одинаковыми вне зависимости от того, какой сегментный регистр ты используешь для доступа к памяти. В этом случае разметка может быть такой:
Код:
org 7C00h
...
rb 7DFEh-$
dw 0AA55h
...
GDTR:
dw GDT_SIZE-1
dd GDT_BASE

align 8
GDT_BASE:
dq 0
desc S_BASE, (S_SIZE+0FFFh)/1000h-1, DF_CODE or DF_DUALACTION or \
DF_PRESENT or DF_USE32 or DF_PAGED ; для сегмента кода
desc S_BASE, (S_SIZE+0FFFh)/1000h-1, DF_DATA or DF_DUALACTION or \
DF_PRESENT or DF_USE32 or DF_PAGED ; для сегмента данных
GDT_SIZE=$-GDT_BASE

align 1000h ; так лучше
S_BASE: org0
use32
entry32:
...
virtual ; 32-разрядный стек, под который нужно распределить память
align 1000h
rb 4000h
S_SIZE=$
end virtual
org S_BASE+$ ; если нужно вернуться к прежней адресации


Писал от руки без проверки. Может, где-нибудь и ошибся. Если нужен текст макроса desc и определение используемых констант, напиши мне.
349
16 октября 2007 года
Phantom-84
656 / / 27.10.2005
Цитата:
а что вы имели ввиду, говоря что org работает иначе?


org не выравнивает текущий адрес на заданное значение, а просто выставляет текущий адрес, равным заданному значению (надеюсь, что ты меня понял :))

Цитата:
чтобы найти какие либо файлы на дискете мне нужно изучить FAT12?

Я тебе (если конечно на wasm.ru писал ты) дважды писал, что ты можешь свободно использовать мой дискетный загрузчик. Нужно лишь изменить основные имена (не расширения) загружаемых файлов. В противном случае, естественно, нужно изучать FAT12, причем досконально.

1.8K
16 октября 2007 года
Evgeni
188 / / 14.06.2006
спасибо, картина стала прояснятся :) на форуме wasm под ником botanic писал я. Благодарб конечно за то что вы мне хотите предложить свой загрузчик, но я не хочу брать чужой))), как то хочется писать свой пусть и по крупицам)). Если у вас инфа по FAT12 буду благодарен если вышлите( мое мыло [email]evgeni-terentev@mail.ru[/email]). Еще раз спасибо

P.S я так пониамю align - выравнивание на границу 1000h или нет?
261
16 октября 2007 года
ahilles
1.5K / / 03.11.2005
align принимает один параметр который указывает на какую границу выравнивать
например
align 8 - выравнивание на границу 8
align 256 - выравнивание на границу 256
все байты которые будут пропущены будут запонятся нулями, либо командами nop
245
16 октября 2007 года
~ArchimeD~
1.4K / / 24.07.2006
в принципе, проще fat12 только fat16. проблем особых возникнуть не должно

я лично гуглем нарыл
http://stormdos.narod.ru/the_oldest/osbk/fs.htm

мне этого хватило для того, чтобы написать загрузку ядра с дискеты, правда на си
349
16 октября 2007 года
Phantom-84
656 / / 27.10.2005
Документацию по FAT12, как верно заметил ~ArchimeD~, можно найти в сети. Желаю всяческих успехов.

Цитата:
P.S я так пониамю align - выравнивание на границу 1000h или нет?

да.

[quote="~ArchimeD~"]мне этого хватило для того, чтобы написать загрузку ядра с дискеты, правда на си[/quote]Ты что загрузчик из бутсектора на Си писал? :D

245
16 октября 2007 года
~ArchimeD~
1.4K / / 24.07.2006
Цитата: Phantom-84

Ты что загрузчик из бутсектора на Си писал? :D



млин, чет я ступил :) . бутсектор конечно на асме, но про него как-то уже забыл, настолько ядром щас занят :D частично на асме, частично на си второй загрузчик.

1.8K
16 октября 2007 года
Evgeni
188 / / 14.06.2006
спасибо всем, извините что задаю вопрос не в тему))
вопрос про опкоды
сразу говорю читал инфу на wasm'е понятно, но ест один вопрос, а если я использую 16 или 8 битный регистр, то что нужно сделать, а то на wasme не было примера, также читал в справочнике Юрова, там это тоже как-то неподробно написано, плиз помогите


и откуда взять индексы 8 и 16 битных регистров, что бы вписать их в modr/m
252
16 октября 2007 года
koderAlex
1.4K / / 07.09.2005
ты что ли в кодах писать собрался ?
то что надо напишет компилятор .
mov al,6 - работа с восьмибитным регистром .
mov ax,6 - с шестнадцатибитным .
mov eax,6 - с тридцатидвухбитным .
349
16 октября 2007 года
Phantom-84
656 / / 27.10.2005
Evgeni, индексы операндов-регистров такие:
0 - al/ax
1 - cl/cx
2 - dl/dx
3 - bl/bx
4 - ah/sp
5 - ch/bp
6 - dh/si
7 - bh/di

fasm немного иначе транслирует команды вида opcode reg, reg, нежели другие компиляторы.

По теме... кто надумает писать буткод для CD, можно скооперироваться... Мне интересен формат CDFS.
1.8K
23 октября 2007 года
Evgeni
188 / / 14.06.2006
Спасибо, Phantom-84.
koderAlex, хочу сказать, что я не собираюсь писать в опкодах, я же написал, что вопрос не потеме
1.8K
30 октября 2007 года
Evgeni
188 / / 14.06.2006
Извините за такой вопрос, но у меня не получается загрузить второй сектор в память, моя прога весит 1024 байта, в память загружается только первый сектор, но в коде есть jmp на метку которая находится в самом начале второго сектора, так вот как правильно его загрузить через функцию 02h прерывания int 13h ( и если можно скажите, как считать сектора на каком-либо цилиндре и сколько их на каждом целиндре)
30K
30 октября 2007 года
alcher
15 / / 25.10.2007
Лучше сделай отдельно программу и отдельно загрузчик.

Про устройство накопителей можешь почитать здесь

http://www.whatis.ru/hard/hdd1.shtml
349
30 октября 2007 года
Phantom-84
656 / / 27.10.2005
Evgeni, у тебя же вроде дискета была. Там не цилиндры, а треки или по другому дорожки. Диски логически представляются так, что на всех цилиндрах одинаковое число секторов. Навряд ли тебе нужно количество всех секторов на отдельно взятом цилиндре. Скорее всего тебе нужно количество секторов на одной поверхности цилиндра. Так вот и у дискет, и у жестких дисков это значение может быть различным. Однако для стандартных 1,44-мегабайтных дискет количество секторов на одной стороне дорожки равно 18, а у большинства современных жестких дисков число секторов на одной поверхности цилиндра устанавливается равным 63. В любом случае, чтобы прочитать второй по счету сектор диска, нужно увеличить только координату "сектор", оставив другие координаты прежними, т.е. использовать тройку координат C=0, H=0, S=2.
1.8K
06 ноября 2007 года
Evgeni
188 / / 14.06.2006
Спасибо Phantom-8, помогло, а теперь вот такая фигня, VMware ругается, когла я запускаяю вот этот код, в чем проблема? В нем я хочу перейти в защищенный режим( знаю что в первом загрузчике это не рекомендуется, но все же я решил пока сделать так). вроде все правильно сделал, но при этом строка не выводится
плиз, подскажите, что не так
245
06 ноября 2007 года
~ArchimeD~
1.4K / / 24.07.2006
а где у тебя, пардон, 32-битный код, который начинается в защищенном режиме и прыжок в него?

вот кусок рабочего кода на nasm:

 
Код:
...
jmp dword 0x8:Pm
[BITS 32]
Pm:
...
1.8K
06 ноября 2007 года
Evgeni
188 / / 14.06.2006
написал в коде так
use32
protected_code:

но все равно vmware ругается
245
06 ноября 2007 года
~ArchimeD~
1.4K / / 24.07.2006
во-первых, возьми в привычку писать, как и на что ругается, во вторых нужно ещё прыжок сделать
6.0K
06 ноября 2007 года
artyom-tyanutov
107 / / 10.07.2006
У тебя:
 
Код:
db 0xea
dw protected
dw 0x8

Надо:
 
Код:
db 0x66
db 0xea
protected:
dd 0
dw 0x8

protected еще и считать надо к твоему сведению!
Посмотри на wasm.ru!
349
06 ноября 2007 года
Phantom-84
656 / / 27.10.2005
В принципе можно использовать и 16-разрядный дальний переход, если внутрисегментное смещение в дальнем адресе не превосходит 0xFFFF. Но в фасме все еще проще, т.к. подобную инструкцию можно писать в явном виде. Вот код из моей оси:
 
Код:
if entryproc < 10000h
                jmp     KCODE:entryproc
else
                jmp     fword KCODE:entryproc
end if


Кроме того, я заметил в исходнике одно несоответствие. Сигнатура бутсектора естественно должна находиться в конце первого сектора, а не в конце второго, т.е. правильно для твоих двух секторов так:
 
Код:
org 7C00h
; код для первого сектора
rb 7DFEh-$
db 55h, 0AAh
; код для второго сектора
rb 8000h-$
; если нужно явно заполнить второй сектор до конца,
; то можно написать так: times 8000h-$ db 0


Ну и далее по мелочам:
 
Код:
;--вычисляем размер GDT----
                 
                 mov cx,4
                 shl cx,3
                 dec cx
             ;--------------------------
             
                 mov [GDT_limit],cx
Никто так не делает! Правильнее так:
 
Код:
mov [GDT_limit], 4*8-1
А еще лучше так:
 
Код:
GDTR:
dw 4*8-1
dd GDT
349
06 ноября 2007 года
Phantom-84
656 / / 27.10.2005
Кстати, даже в прикладных программах никто стек в исполняемом файле не хранит, а в данном случае тем более этого делать не нужно. В твоем распоряжении вся доступная память. На первых порах можешь организовать стек под адресом 7C00h.
349
06 ноября 2007 года
Phantom-84
656 / / 27.10.2005
Кстати, нет необходимости инициализировать дескрипторы явно, т.к. GDT у тебя тоже находится в образе, а все данные статичны, т.е. находятся по известным адресам. Вот пример из Линукса:
Код:
gdt:
    .word   0, 0, 0, 0          # dummy
    .word   0, 0, 0, 0          # unused

    .word   0xFFFF              # 4Gb - (0x100000*0x1000 = 4Gb)
    .word   0               # base address = 0
    .word   0x9A00              # code read/exec
    .word   0x00CF              # granularity = 4096, 386
                        #  (+5th nibble of limit)

    .word   0xFFFF              # 4Gb - (0x100000*0x1000 = 4Gb)
    .word   0               # base address = 0
    .word   0x9200              # data read/write
    .word   0x00CF              # granularity = 4096, 386
                        #  (+5th nibble of limit)


У меня еще проще:
 
Код:
DFLAGS = DF_DUALACTION or DF_PRESENT or DF_USE32 or DF_PAGED

                align   8
INIT_GDT_BASE:  dq      0
                desc    0, 0, DF_DATA or DF_EXTENDED or DFLAGS
                desc    KIMAGE_BASE, (GDT+0FFFh)/1000h-1, DF_CODE or DFLAGS
                desc    KIMAGE_BASE, (GDT+0FFFh)/1000h-1, DF_DATA or DFLAGS
                INIT_GDT_SIZE = $-INIT_GDT_BASE
1.8K
07 ноября 2007 года
Evgeni
188 / / 14.06.2006
artyom-tyanutov, сделал так как ты посоветовал, но там наверно
не protected: а dw protected, но при этом все равно не пашет.
vwware выдает следующую ошибку

И еще слышал про линию A20, но я ее не использовал, может кто скажет зачем она нужна
245
07 ноября 2007 года
~ArchimeD~
1.4K / / 24.07.2006
Включение A20 нужно для обращени к адресам памяти за пределами 1 мб. что будет, если ее не включить и обратиться, я точно не знаю, но кажись адрес 0x40000001 будет считаться за 0x1, 0x40000002 за 0x2 и т.д.

З.Ы. а флоп то есть? попробуй комп со своей дискеты загрузить - что тебе скажет...
349
07 ноября 2007 года
Phantom-84
656 / / 27.10.2005
Когда линия A20 отключена, можно обращаться только к 1, 3, 5 и т.п. мегам памяти. Пока используешь физическую память в пределах первого мега, насчет A20 можно не париться.
6.0K
07 ноября 2007 года
artyom-tyanutov
107 / / 10.07.2006
А какой это тогда за битик на адресной линии???
349
07 ноября 2007 года
Phantom-84
656 / / 27.10.2005
А разве из названия не ясно, что 20-ый???
6.0K
07 ноября 2007 года
artyom-tyanutov
107 / / 10.07.2006
Цитата: Phantom-84
А разве из названия не ясно, что 20-ый???



Блин точно!

1.8K
07 ноября 2007 года
Evgeni
188 / / 14.06.2006
извините снова за вопрос:
но подскажите как точно нужно совершить прыжок: в моем случае код начинается с метки protected_code:, плиз ответте
349
07 ноября 2007 года
Phantom-84
656 / / 27.10.2005
Вроде бы по этому поводу я уже отписался!
 
Код:
if protected_code < 10000h
                jmp     code_selector:protected_code
else
                jmp     fword code_selector:protected_code
end if
1.8K
07 ноября 2007 года
Evgeni
188 / / 14.06.2006
все равно при этом вылазиет эта ошибка, может быть это потому что я пытаюсь выйти в защищенный режим в vmware? я даже в самом начале кода для PM написал бесконечный цикл, что бы хоть проверить, зашел ли я в PM, однако ошибка не устраняется
349
07 ноября 2007 года
Phantom-84
656 / / 27.10.2005
Если речь о той ошибке, что ты показывал, то, как мне кажется, дело совсем не в твоем коде. На bochs пробовал запускать?

Кроме того, я так и не понял, как у тебя обстоят дела с сегментами. Покажи обновленный исходник.
391
07 ноября 2007 года
Archie
562 / / 03.02.2005
А стек не забыл инициализировать перед прыжком в защищенный режим? В ss селектор данных нужно загнать.
6.0K
07 ноября 2007 года
artyom-tyanutov
107 / / 10.07.2006
А может действительно с ГПТ что не так?
Такие вещи лучше бочсем запускать, так как он выводит регистры и ошибочную ситуацию при крахе!
349
07 ноября 2007 года
Phantom-84
656 / / 27.10.2005
Там много чего не так. Например, уже в PM после вывода строки будут выполняться данные. Хотя бы jmp $ напиши. Стек размером 265 байт - это круто. Может, ты хотел написать 256. И даже если так, то его лучше все-таки выровнять на границу слова.
349
07 ноября 2007 года
Phantom-84
656 / / 27.10.2005
Вот что выдает bochs.
Код:
[CPU0 ] branch_far: RIP > limit
[CPU0 ] interrupt(): gate descriptor is not valid sys seg
[CPU0 ] interrupt(): gate descriptor is not valid sys seg
[CPU0 ] protected mode
[CPU0 ] CS.d_b = 16 bit
[CPU0 ] SS.d_b = 16 bit
[CPU0 ] | EAX=00000011  EBX=00007d50  ECX=00007e92  EDX=00000fa0
[CPU0 ] | ESP=00007c00  EBP=00000000  ESI=00007d28  EDI=0000ffde
[CPU0 ] | IOPL=0 id vip vif ac vm RF nt of df if tf sf zf af PF cf
[CPU0 ] | SEG selector     base    limit G D
[CPU0 ] | SEG sltr(index|ti|rpl)     base    limit G D
[CPU0 ] |  CS:0000( 1e00| 0|  0) 00000000 0000ffff 0 0
[CPU0 ] |  DS:0000( 0000| 0|  0) 00000000 0000ffff 0 0
[CPU0 ] |  SS:0000( 0000| 0|  0) 00000000 0000ffff 0 0
[CPU0 ] |  ES:0000( 0000| 0|  0) 00000000 0000ffff 0 0
[CPU0 ] |  FS:0000( 0000| 0|  0) 00000000 0000ffff 0 0
[CPU0 ] |  GS:0000( 0000| 0|  0) 00000000 0000ffff 0 0
[CPU0 ] | EIP=00007cdd (00007cdd)
[CPU0 ] | CR0=0x00000011 CR1=0 CR2=0x00000000
[CPU0 ] | CR3=0x00000000 CR4=0x00000000
[CPU0 ] >> jmp far 0008:7e00 : EA007E0800
[CPU0 ] exception(): 3rd (13) exception with no resolution, shutdown status is 00h, resetting
Проблема с сегментацией, как я и предполагал.
349
07 ноября 2007 года
Phantom-84
656 / / 27.10.2005
Набросал работоспособный вариант. Может, поможет.
Код:
include "desc.inc"

VIDEOSEL        equ     8
CODESEL         equ     10h
DATASEL         equ     18h

                org     7C00h
start:          xor     ax, ax
                cli
                mov     ss, ax
                mov     sp, start
                sti
                jmp     0:@f

@@:             lgdt    [ss:GDTR]
                cli
                mov     eax, cr0
                or      al, 1
                mov     cr0, eax
                jmp     CODESEL:@f

@@:             mov     ax, DATASEL
                mov     ds, ax
                mov     fs, ax
                mov     gs, ax
                mov     ss, ax
                push    VIDEOSEL
                pop     es
                xor     di, di
                cld
                mov     ax, 3320h
                mov     cx, 80*25
                rep     stosw
                jmp     $

GDTR:           dw      4*8-1
                dd      GDT

                align   8
GDT:            dq      0
                desc    0B8000h, 7FFFh, DF_PRESENT or DF_DATA or DF_DUALACTION
                desc    0, 0FFFFh, DF_PRESENT or DF_CODE or DF_DUALACTION
                desc    0, 0FFFFh, DF_PRESENT or DF_DATA or DF_DUALACTION

                rb      7DFEh-$
                dw      0AA55h
6.0K
08 ноября 2007 года
artyom-tyanutov
107 / / 10.07.2006
Хм, только вот не понимаю зачем переходить в ПМ из boot-сектора?
Гораздо более большая проблема это работа с флоппом и ФС, ИМХО!
349
08 ноября 2007 года
Phantom-84
656 / / 27.10.2005
Читай выше. Я уже обращал на это внимание. Аффтар принципиально не хочет юзать чужие загрузчики, но зато побыстрее хочет перейти в PM. К слову, PM c 16-разрядными сегментами, без страничной переадресации вообще не очень-то и от RM отличается. Вопрос про 32-разрядный код был поднят давно, но в исходнике он вообще не представлен.
1.8K
11 ноября 2007 года
Evgeni
188 / / 14.06.2006
Вот посмотрите пожалуйста(если не сложно), правильно ли я создал дескриптор для кода, и правильно ли работает моя функция создания дескриптора, вроде точно разобрался, но при этом ошибка не устраняется

Вопрос к Phantom-84, не можешь ли ты скинуть файл desc.inc, ато у меня его нет, и еще не можешь ли сказать как запустить свой бинарник в bochs( у меня версия 2.3.5)
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог