Page 69 of 77

Re: Помогите новичку

Posted: Fri Aug 21, 2015 4:51 am
by GerdtR
Нашёл я, кого сдвинул. В data32.inc есть кусок данных от метки gdts(строка 236) и до метки gdte. Вставляю строчку "times 200 db 0" перед этими данными - вылетает. Вставляю после них - всё работает. Причём если добавлю 170 байт перед gdts, то работает, добавлю 171 - нет. Найти - нашёл... И? Метка gdts ещё в ядре кое-где используется. Только всё равно не понимаю, как положение этих данных влияет на ОС.

Re: Помогите новичку

Posted: Fri Aug 21, 2015 6:58 pm
by GerdtR
Методом проб и ошибок вывел, что если выровнять gdte по границе 256, то работает. По крайней мере пока не вылетел, посмотрим. Короче баг замазал, но причину вылета всё равно не понял.

Re: Помогите новичку

Posted: Mon Aug 31, 2015 8:23 pm
by MorningStar
Добрый вечер. Подскажите, пожалуйста. Функция #2 возвращает XT-сканкоды с любой клавиатуры? (AT/XT/USB)

Похоже я ошибся. Клавиши стрелок дают не экстишные коды. Ужс, я хотел, по табличке сделать, а придется программой "Сканкоды клавиатуры" все клавиши прозванивать.

Re: Помогите новичку

Posted: Tue Sep 01, 2015 1:00 pm
by Leency
Добрый, функция возвращает и ASCII и SCANCODE. Посмотри http://websvn.kolibrios.org/filedetails ... yascii.asm

Re: Помогите новичку

Posted: Tue Sep 01, 2015 1:37 pm
by MorningStar
Да, я знаю.

Re: Помогите новичку

Posted: Tue Sep 01, 2015 7:57 pm
by MorningStar
И снова здрасьте. Мне опять нужна помощь. Что такое стек потока, и где взять указатель на стек нового потока?
Я гуглил, я смотрел примеры, но ничего не понял. Здесь, например, указатель стека потока взят 0x80000. Если я правильно понял, это указатель стека основного потока (в ассемблере не разбираюсь). Я пишу на С, и не знаю, на что указывает указатель стека основного потока. Как быть?
Альтернативный вопрос. Научите использовать функцию #51 из С-программы.


Все, короче. Посмотрел отладчиком. Указатель стека основного потока совпадает с размером используемой памяти. И если я правильно понимаю, размер используемой памяти вытаскивается функцией 9.

Re: Помогите новичку

Posted: Thu Sep 03, 2015 2:26 am
by GerdtR
Вообще-то стек основного потока ровно там, где выделишь память(ну или зарезервирована) и укажешь в заголовке. Очень часто место резервируют в самом конце программы и указатель, разумеется, указывает на конец используемой памяти. Если нужен новый поток, то или зарезервируй сразу(массив какой сделай, у указатель дай ИмяМассива+РазмерМассива) или выдели функцией #68,12. Ну и указатель также вычисляется.

Re: Помогите новичку

Posted: Thu Sep 03, 2015 3:50 pm
by MorningStar
GerdtR, спасибо. Что-то я промучался, да так и не получилось. Точку входа сделал на void (cfunction(void)) функцию. После создания потока выполняется код этой функции и программа заканчивается.
Кодить под KolibriOS, однако сложно, ибо много чего не понятно, и получается тыканье пальцем в небо.

Re: Помогите новичку

Posted: Thu Sep 03, 2015 8:00 pm
by Pathoswithin
Скажу на всякий случай, что стек растёт из конца в начало. Если выделять под него память, то указывать нужно конец массива. В любом случае, перед указателем должно быть свободное место.

Re: Помогите новичку

Posted: Fri Sep 04, 2015 12:13 am
by MorningStar
Таки не осилил, как правильно сделать.

Code: Select all

void kolibrios_DialogThread(void)
{
    //Helloworld-like code
	__asm__ __volatile__(
    "int $0x40"
    :
    :"a"(63),"b"(1),"c"((uint32_t)('a'))
    :"memory");

    __asm__ __volatile__(
    "int $0x40"
    :
    :"a"(-1)
    :"memory");
}

void DialogsShowSimpleMessageBox(int type, char *title, char *message)
{
    unsigned char *dialogStack;
    dialogStack = malloc(2048);

    __asm__ __volatile__(
    "int $0x40"
    :
    :"a"(51),"b"(1),"c"((uint32_t)kolibrios_DialogThread),"d"((uint32_t)(dialogStack + 2047))
    :"memory");
}
Хотел, чтобы при вызове функции DialogsShowSimpleMessageBox, создавался поток для еще одного окошка. Но после вызова функции, сразу 2 раза вызывается функция kolibrios_DialogThread, пишет "aa" на доске отладки, и на этом программа завершается, не знаю, почему.

А есть программы на С, где можно посмотреть, как это все правильно делается?

Re: Помогите новичку

Posted: Fri Sep 04, 2015 11:17 am
by Veliant
Если используете menuetlibc то там есть функция create_thread


У меня другое API, но выглядит примерно следующим образом

Code: Select all

int kos_CreateThread(void *proc, void *data)
{
	uint8_t *stack = malloc(THREAD_STACK_SIZE);
	if (!stack)
		return -1;
	uint32_t *new_esp = (uint32_t *)&stack[THREAD_STACK_SIZE-sizeof(size_t)*2];
	new_esp[0] = (uint32_t)kos_ExitApp;
	new_esp[1] = (uint32_t)data;
	return syscall4(51, 1, (unsigned)proc, (unsigned)new_esp);
}
В нем аллоцируется память под стек, в последний dword пишется аргумент функции, в предпоследний пишется ret-адрес на функцию корректно завершающую поток на случай если программист не вызовет ее явно

Re: Помогите новичку

Posted: Tue Sep 08, 2015 9:56 pm
by GerdtR
Всё таки не понимаю, почему у меня вылетает ядро: вылетает на 302 строке в kernel.asm: jmp pword os_code:high_code. В боксе смотрю код по high_code - всё нормально. Но шаг - и вылет. Данные в gdts никто не затирает. Не понимаю.

Re: Помогите новичку

Posted: Sun Oct 04, 2015 2:52 am
by Yason
Судя по описанию с.ф. 4, можно делать вывод строки, в область пользователя.
Spoiler:======================================================================
============== Функция 4 - вывести строку текста в окно. =============
======================================================================
Параметры:
* eax = 4 - номер функции
* ebx = [координата по оси x]*65536 + [координата по оси y]
* ecx = 0xXYRRGGBB, где
* RR, GG, BB задают цвет текста
* X=ABFF (биты):
* A=1 - выводить ASCIIZ-строку
* B=1 - закрашивать фон цветом edi
* FF задает шрифт и кодировку:
0 = 6x9 cp866
2 = 8x16 UTF-16LE
3 = 8x16 UTF-8
* Y=CDDD (биты):
* C=1 перенаправить вывод в область пользователя, задано в edi
* DDD = (множитель размера)-1, то-есть 0 = x1, 7 = x8
* edx = указатель на начало строки
* esi = для A=0 длина строки, для A=1 игнорируется
* edi = если B=1, цвет для закраски фона,
если C=1, указатель на область пользователя

Возвращаемое значение:
* функция не возвращает значения
Замечания:
* C=1, цвет = 32 бита, область пользователя выглядит так:
Xsize = dword
Ysize = dword
остаток области = Xsize*Ysize*4
* Нельзя одновременно использовать B=1 и C=1,
поскольку в обоих случаях используется регистр edi.

======================================================================
Область пользователя, насколько я понял - буфер, в котором будет сформирована строка. Так вот, пробовал сделать вывод одного символа, таким образом...
Spoiler:

Code: Select all

char_coord_x = 10
char_coord_y = 10
char_width  = 6
char_height = 9

        ; draw one char in buffer.
        xor     eax, eax
        mov      al, 4
        mov     ebx, char_coord_x
        shl     ebx, 16
        add     ebx, char_coord_y
        xor     ecx, ecx
        mov      cl, 00001000b    ; XY ; X = font type 6x9 cp866 ; Y = output in buffer.
        ror     ecx, 8
        add     ecx, 0x00ff0000   ; char color is red.
        mov     edx, string       ; edx = char start address (H character).
        mov     esi, 1            ; use one char.
        mov     edi, char_addr    ; edi = buffer address for char.
        int     0x40

        ; draw character image.
        xor     eax, eax
        mov      al, 65
        mov     ebx, char_addr    ; ebx = buffer address with char.
        mov     ecx, char_width
        shl     ecx, 16
        add     ecx, char_height
        mov     edx, char_coord_x
        shl     edx, 16
        add     edx, char_coord_y
        mov     esi, 32           ; 32 bits per pixel.
        mov     edi, 0
        mov     ebp, 0
        int     0x40
но тщетно :cry: , символ не выводится, либо вообще всё виснет. Не могу понять, в чём дело. Может быть я, что-то делаю не так? :? Как сделать вывод одного символа, через буфер? Прошу помощи!

Полный тестовый файл прикрепил.

Re: Помогите новичку

Posted: Sun Oct 04, 2015 3:25 am
by Anton_K
Yason, а ты обратил внимание на вот эти строки?
область пользователя выглядит так:
Xsize = dword
Ysize = dword
остаток области = Xsize*Ysize*4
То есть, для функции 4 в первых 8 байтах буфера должны быть указаны ширина и высота, а потом уже идут данные о пикселях.

Но в код я особо не вникал, возможно, что проблема в чем-то другом :)

Re: Помогите новичку

Posted: Sun Oct 04, 2015 3:44 am
by Yason
Буфер выделял вот так...

Code: Select all

char_addr:  db  char_width*char_height*4  dup (0x33)