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

Applications development, KoOS API questions
  • Методом проб и ошибок вывел, что если выровнять gdte по границе 256, то работает. По крайней мере пока не вылетел, посмотрим. Короче баг замазал, но причину вылета всё равно не понял.
    Чем больше сыра, тем больше в нём дыр. Чем больше дыр, тем меньше в нём собственно сыра. Значит, чем больше сыра, тем меньше сыра!
  • Добрый вечер. Подскажите, пожалуйста. Функция #2 возвращает XT-сканкоды с любой клавиатуры? (AT/XT/USB)

    Похоже я ошибся. Клавиши стрелок дают не экстишные коды. Ужс, я хотел, по табличке сделать, а придется программой "Сканкоды клавиатуры" все клавиши прозванивать.
  • Добрый, функция возвращает и ASCII и SCANCODE. Посмотри http://websvn.kolibrios.org/filedetails ... yascii.asm
    Из хаоса в космос
  • Да, я знаю.
  • И снова здрасьте. Мне опять нужна помощь. Что такое стек потока, и где взять указатель на стек нового потока?
    Я гуглил, я смотрел примеры, но ничего не понял. Здесь, например, указатель стека потока взят 0x80000. Если я правильно понял, это указатель стека основного потока (в ассемблере не разбираюсь). Я пишу на С, и не знаю, на что указывает указатель стека основного потока. Как быть?
    Альтернативный вопрос. Научите использовать функцию #51 из С-программы.


    Все, короче. Посмотрел отладчиком. Указатель стека основного потока совпадает с размером используемой памяти. И если я правильно понимаю, размер используемой памяти вытаскивается функцией 9.
  • Вообще-то стек основного потока ровно там, где выделишь память(ну или зарезервирована) и укажешь в заголовке. Очень часто место резервируют в самом конце программы и указатель, разумеется, указывает на конец используемой памяти. Если нужен новый поток, то или зарезервируй сразу(массив какой сделай, у указатель дай ИмяМассива+РазмерМассива) или выдели функцией #68,12. Ну и указатель также вычисляется.
    Чем больше сыра, тем больше в нём дыр. Чем больше дыр, тем меньше в нём собственно сыра. Значит, чем больше сыра, тем меньше сыра!
  • GerdtR, спасибо. Что-то я промучался, да так и не получилось. Точку входа сделал на void (cfunction(void)) функцию. После создания потока выполняется код этой функции и программа заканчивается.
    Кодить под KolibriOS, однако сложно, ибо много чего не понятно, и получается тыканье пальцем в небо.
  • Скажу на всякий случай, что стек растёт из конца в начало. Если выделять под него память, то указывать нужно конец массива. В любом случае, перед указателем должно быть свободное место.
  • Таки не осилил, как правильно сделать.

    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" на доске отладки, и на этом программа завершается, не знаю, почему.

    А есть программы на С, где можно посмотреть, как это все правильно делается?
  • Если используете 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-адрес на функцию корректно завершающую поток на случай если программист не вызовет ее явно
  • Всё таки не понимаю, почему у меня вылетает ядро: вылетает на 302 строке в kernel.asm: jmp pword os_code:high_code. В боксе смотрю код по high_code - всё нормально. Но шаг - и вылет. Данные в gdts никто не затирает. Не понимаю.
    Чем больше сыра, тем больше в нём дыр. Чем больше дыр, тем меньше в нём собственно сыра. Значит, чем больше сыра, тем меньше сыра!
  • Судя по описанию с.ф. 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: , символ не выводится, либо вообще всё виснет. Не могу понять, в чём дело. Может быть я, что-то делаю не так? :? Как сделать вывод одного символа, через буфер? Прошу помощи!

    Полный тестовый файл прикрепил.
    Attachments
    CharTest.7z (2.09 KiB)
    Downloaded 223 times
  • Yason, а ты обратил внимание на вот эти строки?
    область пользователя выглядит так:
    Xsize = dword
    Ysize = dword
    остаток области = Xsize*Ysize*4
    То есть, для функции 4 в первых 8 байтах буфера должны быть указаны ширина и высота, а потом уже идут данные о пикселях.

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

    Code: Select all

    char_addr:  db  char_width*char_height*4  dup (0x33)
  • Who is online

    Users browsing this forum: No registered users and 9 guests