Page 22 of 77

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

Posted: Thu Sep 22, 2011 2:42 am
by Leency
char line[]="Sausages in the fire!"
word bukva[1]='c';

Code: Select all

inline fastcall copystr(dword ESI,EDI)
{
	$cld
l1:
	$lodsb
	$stosb
	$test al,al
	$jnz l1
}
copystr(#bukva, #line + strlen(#line));

Code: Select all

i=strlen(#line);
line[i]=bukva;
i++;
line[i]='\0';
Оба кода работают.

Вопрос - почему второй вариант не работает без последних двух строк?
Как к строке можно добавить одну букву с минимальными телодвижениями?

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

Posted: Thu Sep 22, 2011 2:51 am
by Mario
\0
Че? Прямой слеш? o_O

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

Posted: Thu Sep 22, 2011 3:01 am
by dunkaist
Leency wrote:Вопрос - почему второй вариант не работает без последних двух строк?
Потому что строка должна заканчиваться нулевым байтом, а, добавляя символ в конец, ты этот байт затираешь.
Leency wrote:Как к строке можно добавить одну букву с минимальными телодвижениями?
Leency wrote:l1:
   $lodsb
   $stosb
   $test al,al
   $jnz l1
Я использую схожую конструкцию, только со scasb (ищет по edi):

Code: Select all

mov edi, string
mov ecx, MAX_LENGTH
xor al, al
repnz scasb
Вроде, так.

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

Posted: Thu Sep 22, 2011 3:12 am
by Leency

Code: Select all

i=strlen(#line);
line[i]=bukva;
i++;
line[i]='\0';
Ах как же я был прав, только можно короче

Code: Select all

i=strlen(#line);
line[i]=bukva;
line[i+1]='\0';
>>Потому что строка должна заканчиваться нулевым байтом, а, добавляя символ в конец, ты этот байт затираешь.
Я думал, что там за строкой одни нули, тоесть:
char line[]= { 'S', 'a', 'u', ........, 'r', 'e', '!', '\0', '\0', '\0', ........ '\0' }

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

Posted: Thu Sep 22, 2011 3:58 am
by Mario
Leency wrote:Я думал, что там за строкой одни нули, тоесть:
char line[]= { 'S', 'a', 'u', ........, 'r', 'e', '!', '\0', '\0', '\0', ........ '\0' }
Нули там только в начале, но на это рассчитывать не стоит даже в начале - для полной надежности, нужно считать что там всегда мусор.

Все же почему '\0' со слешем или цифры обязательно указывать со слешем?.

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

Posted: Thu Sep 22, 2011 6:24 am
by SoUrcerer
Mario wrote: Все же почему '\0' со слешем или цифры обязательно указывать со слешем?.
Ты никогда не замечал, как в том же Linux записываются пути с пробелами? "/path\ with\ probels"
Здесь слеш означает именно символ со специальным кодом. \ или \20 (в некоторых системах \32 тоже сработает) - это пробел, \n - перевод строки (емнип \13 - то же самое), \r - возврат каретки. Ну и так далее :) \0 - это символ с кодом 0

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

Posted: Thu Sep 22, 2011 9:17 am
by Leency
>>Все же почему '\0' со слешем или цифры обязательно указывать со слешем?
Это не просто цифры и просто ноль. '\0' означает конец строки в сях. Цифры со слешем - это код символа.

http://lib.ru/CPPHB/cpptut.txt#51

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

Posted: Mon Sep 26, 2011 9:06 am
by Rock_maniak_forever

Code: Select all

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

------------------ Функция 37.7 - данные прокрутки -------------------
Параметры:
  * eax = 37 - номер функции
  * ebx = 7 - номер подфункции
Возвращаемое значение:
  * eax = [horizontal offset]*65536 + [vertical offset]
Замечания:
  * Данные доступны только активному окну.
  * После прочтения значения обнуляются.
  * Данные имеют знаковые значения.

======================================================================
У меня вопрос по выше указанной функции.

1.Что значит горизонтальное смещение? Может я отстал от жизни, и на мышки стали делать два колеса?
2.И в каком виде, выдаётся значение смещения?

Пытался сделать данную функцию, но у меня ничего не вышло, работает только часть кода. Мне казалось, что при повароте колеса должны выдаваться значения 1 и -1. То есть, к примеру, при повароте колеса вверх, должна выдаваться 1, вниз -1, а когда не вертится 0. Код прилогается.

Code: Select all


      xor     eax,eax                                 ; Функция 37.7: Получить данные прокрутки колёсика мыши.
      mov     al,37                                   ; ------------------------------------------------------
      xor     ebx,ebx                                 ; -----------------
      mov     bl,7                                    ; номер подфункции.
      int     0x40                                    ; вызываем системное прерывание.

      mov     ebx,eax                                 ; eax = ebx.
      shr     eax,16                                  ; horizontal offset, сдвигаем в регистр ax. eax = horizontal offset.
      and     ebx,0x0000ffff                          ; обнуляем старшие 2 байта в регистре ebx. ebx = vertical offset.

      cmp      bx,word 1
      jne      @f

      call     func.MOVE_SCROLLER_UP
      jmp      END
   @@:
      cmp      bx,word -1
      jne      END

      call     func.MOVE_SCROLLER_DOWN
      jmp      END

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

Posted: Mon Sep 26, 2011 9:20 am
by Mario
1. Да это для двухколесной мышки.
2. Смещение выдается относительно старого положения колеса, которое принимается за ноль. Если поворот в другую сторону, то значение отрицательное, т.е. старший бит 16 битного числа знаковый.
3. Значение может быть больше 1 и -1.

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

Posted: Mon Sep 26, 2011 10:03 am
by Rock_maniak_forever
Спасибо! Сейчас попробую.

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

Posted: Mon Sep 26, 2011 11:30 am
by Rock_maniak_forever
Да, теперь всё работает. :D В общем, надо было сделать так...

Code: Select all


START:
      xor     eax,eax                                 ; Функция 37.7: Получить данные прокрутки колёсика мыши.
      mov     al,37                                   ; ------------------------------------------------------
      xor     ebx,ebx                                 ; -----------------
      mov     bl,7                                    ; номер подфункции.
      int     0x40                                    ; вызываем системное прерывание.

      mov     ebx,eax                                 ; eax = ebx.
      shr     eax,16                                  ; horizontal offset, сдвигаем в регистр ax.eax = horizontal offset
      and     ebx,0x0000ffff                          ; обнуляем старшие 2 байта в регистре ebx.ebx = vertical offset

      test    bx,bx
      jz      END

      cmp     bx,word 1
      je      @f

      call    func.MOVE_SCROLLER_UP
      jmp     END
@@:
      cmp     bx,word -1
      je      END

      call    func.MOVE_SCROLLER_DOWN
END:
P.S. **********************************************************************************************************************************************
Mario wrote:1. Да это для двухколесной мышки.
2. Смещение выдается относительно старого положения колеса, которое принимается за ноль. Если поворот в другую сторону, то значение отрицательное, т.е. старший бит 16 битного числа знаковый.
3. Значение может быть больше 1 и -1.
Кстати говоря, я думаю, надо бы это описание внести в документацию, а тож непонятно. :roll:

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

Posted: Mon Sep 26, 2011 9:00 pm
by Mario
Почему ты проверяешь bl? Когда число отрицательное это может привести к неправильному результату. Надо всегда работать с bx.

Если ты подзабыл:
ebx = 16 старших разрядов и bx
bx = bh и bl

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

Posted: Tue Sep 27, 2011 12:13 am
by Rock_maniak_forever
Оптимизация, мать её. Забыл, что знак хранится в bh. :D

А зачем сис. функция, использует WORD, для одного значения? Это же не оптимально. Вполне хватило бы и байта. :mrgreen:

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

Posted: Fri Oct 21, 2011 11:59 pm
by Антон
Всем привет!
Я недавно начал баловаться с OSDev. Пока написал LiveUSB танчики. Часть кода смотрел, как реализована в KolibriOS, и делал под себя.
Но одну важную для меня вещь не могу никак найти в исхах колибри: если компьютер был загружен с диска N, как получить номер этого диска на шине ATA? Или если это флешка, как определить, что это флешка?

Posted: Sun Oct 30, 2011 9:50 pm
by 0CodErr
Здравствуйте!
Установил KolibriOS. Опробовал. Заинтересовался.
Скачал мануал "Документация по программированию в KolibriOS". Стал изучать, но вопросов появилось очень много.

Потом нашёл SDK. Изучил примеры. Потом в wiki прочитал про функционирование ядра — стало чуть понятнее. Но, тем не менее, осталась куча вопросов, например, что происходит во время загрузки программы (что куда загружается, как создаётся поток), про память и стек (например, бэйсик для Menuet почему-то начинает программу с mov esp, %вершина стека% и определяет громадные значения для памяти приложения — как должно быть на самом деле и от чего зависит я не понял).

Постоянно перегружаться, чтобы проверить, совсем неудобно. Я узнал про эмулятор. Стало проще. Но он (не удивительно) или не полностью эмулирует, или не так как надо, или что-то не поддерживает. Поэтому всё равно приходится перегружаться, но с эмулятором гораздо меньше.

Потом я начал писать простенькие программки (просто, чтобы проверить, как работает та или иная функция и какой результат она выдаёт).

Недавно я написал 2 программки: одна выдаёт информацию о потоке с активным окном, а другая — о потоке, окно которого под указателем мыши.
Теперь ещё прибавилось вопросов:
в мануале написано "Обычные приложения размещаются в памяти по адресу 0x60400000" — когда я получаю информацию о потоке, то адрес процесса в памяти = 0, и приложение CPU тоже так показывает для всех потоков. Как должно быть на самом деле?

Далее, "11 байт: имя процесса..." — здесь эмулятор (если я не ошибся) ведёт себя не так, как Kolibri. А как на самом деле? То есть, если имя меньше 11 символов, то ставится завершающий 0 или заполняется пробелами? И всегда ли это происходит одинаково?

Ещё эмулятор про клиентские размеры выдавал какую-то чепуху.

Потом я загрузил Kolibri. Запустил свои программки. И узнал ещё чуть больше. Например (если это не моя ошибка), сам рабочий стол, поток ICON, со временем менял свой ID, а это, согласно мануалу, невозможно: "идентификаторы монотонно растут", "не изменяются со временем для заданного потока", "Идентификатор потока не может быть назначен другому потоку даже после завершения первого." Значит этот поток завершался, а вместо него запускался его "близнец"(ну или он же перезапускался просто).

А что происходит во время переключения потоков? В эмуляторе иногда показывало "OS/IDLE", в Kolibri не заметил такого. (я тут имею ввиду, тот промежуток, когда "от первого потока мы ушли уже, а второй ещё как бы не успел активироваться")

Теперь вопрос про основной цикл прораммы. Если нужно просто реагировать на события — то я использую функцию ожидания события.
Но как быть, если нужно и реагировать на события и кроме этого ещё постоянно что-то выполнять? Я решил переключаться на следующий поток (эмулятор опять сказал, что не знает такую функцию). Пусть система сама решит, какой следующий, и когда вернуться опять к этому (но пока, насколько я понял, для всех потоков время одинаковое). Или же, можно было ждать событие некоторое время. Как в этом случае было бы правильнее делать (ждать или переключаться)?

Когда я (всё-таки) сделал скриншот моих программок, скриншотер сделал что-то с рабочим столом. От чего это так? Может, надо было что-то ещё настроить или я что-нибудь не то нажал?

Может ли Kolibri работать с PATA? У меня сначала не определялись диски, потом я в BIOS оставил только SATA(а было PATA+SATA).

Image

Image