Вопросы по программированию

Автор Богдан, 03 Листопад 2007, 11:41:18

Попередня тема - Наступна тема

firefire

Цитата: edd_k від 27 Січень 2009, 19:11:03
Стало интересно - расчехлил BP7, получилось так:

const
  space: set of char = [#9, #10, #13, #32];

var
  i, n, count: integer;
  s: string;

begin
  ReadLn(s);

  n:= Length(s);
  count:= 0;
  i:= 1;

  while (i <= n) do
  begin
    while ((i <= n) and (s[i] in space)) do Inc(i);
    if (i <= n) then
    begin
      Inc(count);
      while ((i <= n) and not (s[i] in space)) do Inc(i);
    end;
  end;

  WriteLn('*** ', count, ' words ***');
end.

ОМГ. Ты извращенец  ;D . Использовать 3 цикла while.. это кое-что  :-[

немой

visual. критикуйте, кому не лень =)
// dpk_pr.cpp : main project file.

#include "stdafx.h"
#include "iostream"
#include "string"
#include "conio.h"
using namespace std;

int main ()
{
  string lines;
  int word=1; //стандартно слов на 1 больше пробелов
  cout<<"text:\n";
  getline (cin, lines);
  if (lines[lines.size()-1]==' ') word--; //учитывается последний символ-пробел
  if (lines[0]==' ') word--; //учитывается первый символ-пробел
  for (int i=0; i!=lines.size(); i++)
    {
    if (lines[i]==' ' && lines[i+1]!=' ')
word++;

    }

cout<<word;
getch();
  return 0;
}

Edd.Dragon

Цитата: firefire від 27 Січень 2009, 23:19:20
ОМГ. Ты извращенец  ;D . Использовать 3 цикла while.. это кое-что  :-[
Ты же в своем коде использовал функции копирования, поиска и удаления. А подставь в свой код их исходники - у тебя получится тоже куча циклов. Или они без циклов реализованы? ))) Только лишнего кода будет в разы больше, т.к. функции универсальны.

Циклов не может быть много или мало - их может быть столько, сколько нужно. Компьютер по тыщу раз в секунду выполняет массу повторяющихся (циклических) действий. Т.к. "повторить что-то для ряда данных" - это естественная задача для процессора.

С теми внутренними циклами получается меньше проверок символов. Без циклов каждый символ проходит проверку по 2 раза, при чем последний сивол нужно проверять вне цикла, т.к. для последнего символа нет следующего.


Цитата: немой від 29 Січень 2009, 00:05:16
visual. критикуйте, кому не лень =)
Как уже говорилось - пробелов может быть несколько подряд, а у тебя учитывается что спереди и сзади может быть только по одному пробелу.

Если же ввести строку, состоящую только из пробелов (двух или более), то у тебя вообще получится -1 слово )))

немой

#553
Цитата: edd_k від 29 Січень 2009, 10:24:50
Если же ввести строку, состоящую только из пробелов (двух или более), то у тебя вообще получится -1 слово )))

эдд, запусти, а?  :-X если одни пробелы, то 0 показывает.
слово =1, -1 идет за первый пробел, -1 идет за последний пробел и +1 идет с цикла, скорее всего за последний круг.
если завести пробелпробелпробелАААпробепробелпробел, то будет 1 слово.

апдейт, пруфпики:

Edd.Dragon

Ага, я не обратил внимание на твой цикл. Ты там вылезаешь за пределы длины массива. Но поскольку в стандартном классе string там "законечный" нулевой символ, т.е. все корректно, т.к. строка длиной n на самом деле представлена массивом длиной n+1.

Мда, с первого разу и не сообразил ))))))

firefire

У меня есть маленький вопрос. Вот у меня есть код
program p1;
var n,i,k:longint;
begin
  Readln(n);
  Writeln("----------");
  k:=n div 2;
  for i:=1 to k do
  begin
    If (n mod i=0) then
      writeln(i);
  end;
  Readln;
end.

Он находит все делители числа n, как видите. Но если в значение числа n поставить 3ккк например. То процесс затянется не на 10 секунд, а на несколько минут  :(.
Никто не знает другой алгоритм?

Garfi


βεερ_βooρ

Цитата: firefire від 01 Лютий 2009, 08:29:53
У меня есть маленький вопрос. Вот у меня есть код
program p1;
var n,i,k:longint;
begin
  Readln(n);
  Writeln("----------");
  k:=n div 2;
  for i:=1 to k do
  begin
    If (n mod i=0) then
      writeln(i);
  end;
  Readln;
end.

Он находит все делители числа n, как видите. Но если в значение числа n поставить 3ккк например. То процесс затянется не на 10 секунд, а на несколько минут  :(.
Никто не знает другой алгоритм?
Детерминированый алгоритм нахождение делителей - экспонинциально-сложный. Улучшить сложность можно только используя супертьюринговый вычислитель или вероятносный алгоритм.
Fear is the path to the dark side. Fear leads to anger. Anger leads to hate. Hate leads to suffering.
All that's here is Fear! Suppression! Betrayal! Despair! Contempt! Regret! Sadness! Anguish! Madness! And Pain, right?

firefire

Цитата: Garfi від 01 Лютий 2009, 11:40:52
поясни это... ???
Цикл for от 1 до k. Что тут не понятно? Или ты забыл конструкцию Pascal?  ;D
Цитата: beep_boop від 01 Лютий 2009, 13:04:25
Детерминированый алгоритм нахождение делителей - экспонинциально-сложный. Улучшить сложность можно только используя супертьюринговый вычислитель или вероятносный алгоритм.
Но это же тупо. Проверять на кратность все числа от 1 до k div 2! Ты точно не помнишь какой-то другой алгоритм?

βεερ_βooρ

Цитата: firefire від 01 Лютий 2009, 14:23:58
Но это же тупо. Проверять на кратность все числа от 1 до k div 2! Ты точно не помнишь какой-то другой алгоритм?
Тупо считать что:
1) Все халява, достаточно спросить бупа и он подскажет алгоритм сложности О(1)
2) Сложные вещи должны быть сложыми, а простые - простыми.
Разложение на множители - NP-полная проблема, нету алгоритма ее решения за полимениальное время. Есть сложные класические алгоритмы, но все они имеют экспоненциальную сложность.
Fear is the path to the dark side. Fear leads to anger. Anger leads to hate. Hate leads to suffering.
All that's here is Fear! Suppression! Betrayal! Despair! Contempt! Regret! Sadness! Anguish! Madness! And Pain, right?

Edd.Dragon

#560
Цитата: firefire від 01 Лютий 2009, 14:23:58
Но это же тупо. Проверять на кратность все числа от 1 до k div 2!
Если это тупо, то другой алгоритм был бы очевиден любому более-менее логически мыслящему индивиду. По крайней мере он бы витал в воздухе.

Да, кстати, именно на временнОй сложности поиска всех делителей и базируется вся криптография. Если бы был иной быстрый алгоритм, то зашифрованное тобой 512-битным ключом письмо взламывалось бы не за миллионы лет (образно, реально наверняка гораздо больше независимо от мощности перебирающего суперкомпа), а за часы или сутки.


Цитата: beep_boop від 01 Лютий 2009, 13:04:25
Детерминированый алгоритм нахождение делителей - экспонинциально-сложный. Улучшить сложность можно только используя супертьюринговый вычислитель или вероятносный алгоритм.
Ну это не повод считать полторы-две тысячи остатков от деления целых несколько секунд, а тем более минут! Если конечно под 3ккк имелось ввиду "порядка трех тысяч"...

Без вывода на экран такой перебор проходит в мгновение ока. С выводом - в мгновение ока + вывод нескольких десятков результатов.

Если же имелось ввиду 3 000 000 000 (т.е. миллиарда), то тогда для начала 3 млрд не влазят в знаковый 32-битный integer. А беззнакового 32-битного целого в досовском BP7 нет.

В досовском Borland C++ 3 расчет что в оконном режиме, что в полноэкранном, что с отображением результов, что без - около 40-41 сек.

Сравнить паскаль и С можно на числе 2 млрд:

Borland C++ 3

#include <iostream.h>

const long k = 2000000000;

int main()
{
  cout << "Start finding dividers for k = " << k << "...\n";

  long n = 1;
  for(long i = 2; i <= k / 2; i++)
  {
     if(k%i == 0)
     {
       n++;
       cout << i << endl;
     }
  }

  cout << "Finded " << n << " dividors\n\n";
  return 0;
}


Borland Pascal 7.1

const
  k: longint = 2000000000;
var
  i, n: longint;
begin
  WriteLn('Start finding for k = ', k, '...');

  n:= 1;
  for i:= 2 to k div 2 do
  begin
    if(k mod i = 0) then
    begin
      Inc(n);
    end;
  end;

  WriteLn('Finded ', n, 'dividors');
end.


Паскаль - 62 сек.
С++ (код под 80386, оптимизации вкл.) - 27 сек.

Используя более современные компиляторы, компилирующие под более новые процессоры, можно надеяться на дальнейшее улучшение результатов. Кроме того, имея 2-ядерный процессор и используя Visual Studio можно без особых доп. знаний разложить расчет на 3-4 потока (при помощи BackgroudWorker), чтобы загрузить оба ядра. Какой прирост получим при этом - не знаю. Поставить что ли VS Express...

βεερ_βooρ

Цитата: edd_k від 01 Лютий 2009, 15:08:09
Да, кстати, именно на временнОй сложности поиска всех делителей и базируется вся криптография.
Ну не вся - основная идея состоит в использовании труднообратимых функций. А тут выбор есть достаточно широк: помимо поиска периода(что эквивалентно факторизации), используется дискретное логарифмирование, элиптческие кривые и еще много умных слов.
Цитата: edd_k від 01 Лютий 2009, 15:08:09
Ну это не повод считать полторы-две тысячи остатков от деления целых несколько секунд, а тем более минут!
Ну поблемы конкретной реализации не снимают проблему в целом. У меня пытались выпытать алгоритм :)
Цитата: edd_k від 01 Лютий 2009, 15:08:09
Какой прирост получим при этом - не знаю. Поставить что ли VS Express...
По закону Амдала прирост будет линейным.
Fear is the path to the dark side. Fear leads to anger. Anger leads to hate. Hate leads to suffering.
All that's here is Fear! Suppression! Betrayal! Despair! Contempt! Regret! Sadness! Anguish! Madness! And Pain, right?

firefire

ЦитатаНу это не повод считать полторы-две тысячи остатков от деления целых несколько секунд, а тем более минут! Если конечно под 3ккк имелось ввиду "порядка трех тысяч"...
3000000000
ЦитатаЕсли же имелось ввиду 3 000 000 000 (т.е. миллиарда), то тогда для начала 3 млрд не влазят в знаковый 32-битный integer. А беззнакового 32-битного целого в досовском BP7 нет.
Вообще-то есть для этого longint
ЦитатаИспользуя более современные компиляторы, компилирующие под более новые процессоры, можно надеяться на дальнейшее улучшение результатов. Кроме того, имея 2-ядерный процессор и используя Visual Studio можно без особых доп. знаний разложить расчет на 3-4 потока (при помощи BackgroudWorker), чтобы загрузить оба ядра. Какой прирост получим при этом - не знаю. Поставить что ли VS Express...
Только у меня проц 1-ядерный, и экспериментировать не на чем.


Edd.Dragon

#563
ЦитатаВообще-то есть для этого longint
В 64-битной среде.

В 16-битной среде (BP7)
int - 16 bit
word - 16 bit
longint - 32 bit (-2 млрд до 2 млрд :P)

В 32-разрядной среде (Дельфи)
int - 32 bit
word - 32 bit (а тут без знака и следовательно влезут числа от 0 до 4 млрд)
longint - 32 bit
Int64 - 64 bit (неэффективное решение, особенно если юзать деление или остаток)

В 64-разрядной среде
int - 64 bit
word - 64 bit


Цитата: firefire від 01 Лютий 2009, 16:54:25
Только у меня проц 1-ядерный, и экспериментировать не на чем.
Да без разницы. На 32-битной платформе нормально можно поэкспериментировать лишь с числами до 4 млрд. А дальше либо использовать "костыли" из спарки двух 32-битных чисел в одно с делением "в столбик" (Int64 в 32-битном Дельфи), что в десятки и сотни раз медленнее (в зависимости от реализации алгоритмов деления и получения остатка), либо же переходить на x64 ось и компилятор.

x-jek

Сделал я наброски сайта на языке хтмл в вёрде,сохранил как вебстраницу,открываю в браузере,а там вместо готовой страницы написан код ее. Можно ли как нибудь просмотреть страницу не заливая на хост?
AMD Athlon X2 4200+, MSI K9NGM4, 2GB Ram, Geforce 8600GT, Samsung 320 GB, Codegen 300 ВТ

Edd.Dragon

Цитата: x-jek від 08 Лютий 2009, 00:32:44
Сделал я наброски сайта на языке хтмл в вёрде,сохранил как вебстраницу,открываю в браузере,а там вместо готовой страницы написан код ее. Можно ли как нибудь просмотреть страницу не заливая на хост?
Можно, запустить браузером. Ему все-равно, откуда ее качать. Так что разбирайся почему показывает код, а не страницу. Т.к. мне не очевидно как именно открывал и что именно открывал. Мож ты разрешение подставил файлу неадекватное или еще чего...

Ivan_32

Все очень просто. В ворде ведь можно сделать страницу уже готовую, а он ее парсит потом в html при сохранении, вот он тебе твой код и распарсил:)
Чем больше я узнаю, тем больше чувствую себя дураком...

x-jek

Я вводил вот этот код
<TITLE>Стих</TITLE>
</HEAD>
<!—Присвоение цвета фону и текста страницы  -->
<BODY BGCOLOR="darkviolet" text="white">
<!—Заголовок, выровненный по центру -->
<H2 align="center">  Пословица</H2
<!—Начало основного текста стиха -->
        Учиться, учиться и еще раз учиться.
<!—Имя автора, выравнивание по правому краю -->
<P align="right"><I>В.И.Ленин</>
</BODY>
</HTML>

Сохранил в формате Htm, что я сделал неправильно?
AMD Athlon X2 4200+, MSI K9NGM4, 2GB Ram, Geforce 8600GT, Samsung 320 GB, Codegen 300 ВТ

Garfi

x-jek, в самом верху добавь <html>. ;)

x-jek

Добавил - все равно код один показывает.
AMD Athlon X2 4200+, MSI K9NGM4, 2GB Ram, Geforce 8600GT, Samsung 320 GB, Codegen 300 ВТ

Garfi

ты с цветами что-то намутил...
у меня этот вариант работает:

Цитата
<HTML>
<TITLE>Стих</TITLE>
</HEAD>
<!—Присвоение цвета фону и текста страницы  -->
<BODY>
<!—Заголовок, выровненный по центру -->
<H2 align="center" >  Пословица</H2>
<!—Начало основного текста стиха -->
   
Учиться, учиться и еще раз учиться.

<!—Имя автора, выравнивание по правому краю -->
<P align="right"><I>В.И.Ленин</>
</BODY>
</HTML>

x-jek

У меня тоже самое, может какие настройки надо в верде включать? у меня офис 2007
AMD Athlon X2 4200+, MSI K9NGM4, 2GB Ram, Geforce 8600GT, Samsung 320 GB, Codegen 300 ВТ

Garfi

x-jek, куда делись те времена, когда HTML-код страницы вручную набирался в блокноте...насколько я помню HTML, цвет нужно указывать или сразу внутри тэга, или в стилях...

Edd.Dragon

#573
Цитата: Garfi від 08 Лютий 2009, 11:52:15
x-jek, куда делись те времена, когда HTML-код страницы вручную набирался в блокноте...насколько я помню HTML, цвет нужно указывать или сразу внутри тэга, или в стилях...
Эти ошибки - не повод отображать вместо некорректной страницы ее код. Кроме того, ошибочные свойсва тегов просто игнорируются.

Но в данном случае строка
<BODY BGCOLOR="darkviolet" text="white">
абсолютно корректна и его код после добавления в начале тега <HTML> работает и показывает ядовито-розовую страничку ))

Цитата: x-jek від 08 Лютий 2009, 11:48:10
У меня тоже самое, может какие настройки надо в верде включать? у меня офис 2007
Открой блокнот, введи вышеуказанный код в нем и сохрани с именем 1.html. Щелкни 2 раза по файлу и если у тебя не страница, а ее код, то при чем тут ворд вообще? html-файл - это тупо текстовый файл, но с расширением html. Нет абсолютно никакой разницы в чем его набрать. Разница только в том, что в одном случае (блокнот) ты набираешь его вручную, а в другом (например, Дримвейвер) визуальными инструментами, которые потом делают за тебя формирование html-а

x-jek

#574
Цитата: edd_k від 08 Лютий 2009, 11:55:35
Открой блокнот, введи вышеуказанный код в нем и сохрани с именем 1.html. Щелкни 2 раза по файлу и если у тебя не страница, а ее код, то при чем тут ворд вообще? html-файл - это тупо текстовый файл, но с расширением html. Нет абсолютно никакой разницы в чем его набрать. Разница только в том, что в одном случае (блокнот) ты набираешь его вручную, а в другом (например, Дримвейвер) визуальными инструментами, которые потом делают за тебя формирование html-а

Спасибо, заработало!
AMD Athlon X2 4200+, MSI K9NGM4, 2GB Ram, Geforce 8600GT, Samsung 320 GB, Codegen 300 ВТ

Edd.Dragon

Цитата: x-jek від 08 Лютий 2009, 12:05:13
Спасибо, заработало!
Ну значит что-то не так сохранял. Или твой браузер неадекватно реагирует на расширение htm )))

x-jek

Цитата: edd_k від 08 Лютий 2009, 12:10:53
Ну значит что-то не так сохранял. Или твой браузер неадекватно реагирует на расширение htm )))

ага, опера, эксплорер и мозилла одновременно обьявили бойкот?)))
AMD Athlon X2 4200+, MSI K9NGM4, 2GB Ram, Geforce 8600GT, Samsung 320 GB, Codegen 300 ВТ

Edd.Dragon

Цитата: x-jek від 08 Лютий 2009, 12:21:22
ага, опера, эксплорер и мозилла одновременно обьявили бойкот?)))
Знать бы четкую последовательность действий для достижения проблемы - я бы поробовал у себя

x-jek

Цитата: edd_k від 08 Лютий 2009, 12:27:03
Знать бы четкую последовательность действий для достижения проблемы - я бы поробовал у себя

не вопрос, могу докладно написать, что я там делал и как добился такой проблемы, что пришлось просить о помощи у спецов.
AMD Athlon X2 4200+, MSI K9NGM4, 2GB Ram, Geforce 8600GT, Samsung 320 GB, Codegen 300 ВТ

Edd.Dragon

так пиши, чего кота за... ухо тянуть )))

x-jek

Значит так, рецепт таков: набрал все это в верде 2007, сохраняешь как вебстраница(там три варианта существует вебстраниц) и все, появившийся файл после сохранения открываешь любым браузером. Вот и все, у меня так было.
AMD Athlon X2 4200+, MSI K9NGM4, 2GB Ram, Geforce 8600GT, Samsung 320 GB, Codegen 300 ВТ

Ivan_32

Вобщем то у меня тоже самое происходит. Страница сохраняется в интерпретацию самой себя на html. Я же говорил код парсится. Вобще не понимаю какой смысл писать код html в ворде, без подсветки синтаксиса..
Использовать ворд для написания кода нерационально, если же вы хотите использовать html -код для форматирования текста то стоит ознакомится с новой спецификацией xml-докумментов Office 2007
Чем больше я узнаю, тем больше чувствую себя дураком...

Andrii

Мдя, може не потемі, але я вважаю найкраще при створені сайту використовувати Adobe Dreamweaver - ІМХО, найкращий редактор коду.

firefire

Цитата: edd_k від 01 Лютий 2009, 15:08:09
Если это тупо, то другой алгоритм был бы очевиден любому более-менее логически мыслящему индивиду. По крайней мере он бы витал в воздухе.

Да, кстати, именно на временнОй сложности поиска всех делителей и базируется вся криптография. Если бы был иной быстрый алгоритм, то зашифрованное тобой 512-битным ключом письмо взламывалось бы не за миллионы лет (образно, реально наверняка гораздо больше независимо от мощности перебирающего суперкомпа), а за часы или сутки.

Ну это не повод считать полторы-две тысячи остатков от деления целых несколько секунд, а тем более минут! Если конечно под 3ккк имелось ввиду "порядка трех тысяч"...

Без вывода на экран такой перебор проходит в мгновение ока. С выводом - в мгновение ока + вывод нескольких десятков результатов.

Если же имелось ввиду 3 000 000 000 (т.е. миллиарда), то тогда для начала 3 млрд не влазят в знаковый 32-битный integer. А беззнакового 32-битного целого в досовском BP7 нет.

В досовском Borland C++ 3 расчет что в оконном режиме, что в полноэкранном, что с отображением результов, что без - около 40-41 сек.

Сравнить паскаль и С можно на числе 2 млрд:

Borland C++ 3

#include <iostream.h>

const long k = 2000000000;

int main()
{
  cout << "Start finding dividers for k = " << k << "...\n";

  long n = 1;
  for(long i = 2; i <= k / 2; i++)
  {
     if(k%i == 0)
     {
       n++;
       cout << i << endl;
     }
  }

  cout << "Finded " << n << " dividors\n\n";
  return 0;
}


Borland Pascal 7.1

const
  k: longint = 2000000000;
var
  i, n: longint;
begin
  WriteLn('Start finding for k = ', k, '...');

  n:= 1;
  for i:= 2 to k div 2 do
  begin
    if(k mod i = 0) then
    begin
      Inc(n);
    end;
  end;

  WriteLn('Finded ', n, 'dividors');
end.


Паскаль - 62 сек.
С++ (код под 80386, оптимизации вкл.) - 27 сек.

Используя более современные компиляторы, компилирующие под более новые процессоры, можно надеяться на дальнейшее улучшение результатов. Кроме того, имея 2-ядерный процессор и используя Visual Studio можно без особых доп. знаний разложить расчет на 3-4 потока (при помощи BackgroudWorker), чтобы загрузить оба ядра. Какой прирост получим при этом - не знаю. Поставить что ли VS Express...

Если это так сложно, то объясни как мне решить эту задачу?

На олимпиаде я решал тупо проверкой. Но если число 10^6 поставить, то код сначало должен проверить каждое число от 1 до 10^6 на количество делителей, а потом уже сравнивать результат.
Олимпиада районная. Ограничение во времени 10 сек. ;) .

Edd.Dragon

Цитата: firefire від 08 Лютий 2009, 22:46:53
Если это так сложно, то объясни как мне решить эту задачу?

На олимпиаде я решал тупо проверкой. Но если число 10^6 поставить, то код сначало должен проверить каждое число от 1 до 10^6 на количество делителей, а потом уже сравнивать результат.
Олимпиада районная. Ограничение во времени 10 сек. ;) .
Какую именно задачу?

Если надо найти все делители не для числа N, а все делители для всех чисел от 1 до N, то естетсвенно тут можно и нужно привинтить приемы для устранения одинаковых проверок.

Обсуждаем уже несколько страниц возможность оптимизации задачи "найти делители числа N", а оказывается это только подзадача. Как всегда.
*злится*

firefire

Цитата: edd_k від 09 Лютий 2009, 10:21:29
Какую именно задачу?

Если надо найти все делители не для числа N, а все делители для всех чисел от 1 до N, то естетсвенно тут можно и нужно привинтить приемы для устранения одинаковых проверок.
Я же тебе сфоткал.
ЦитатаОбсуждаем уже несколько страниц возможность оптимизации задачи "найти делители числа N", а оказывается это только подзадача. Как всегда.
*злится*
Сорри, фотоапарата не было тогда чтобы сфоткать условие  :%)

Ivan_32

#586
Как можно получить адрес конца функции? У меня вот пока такой вариант назрел:
void foo()
{
  _asm
    {
     mov EndAddr,EIP+1
    }
}
Правда я не совсем не понимаю что лежит в EIP в этот самый момент, адрес этой же инструкции, адрес следущей инструкции или адерс предыдущей инструкции. Как это происходит?


1. EIP -> Адрес следущей команды.
2. Выполнение команды.
3. Инкрементирование EIP

Или как?
Да кстати такой еще вопрос. Поместить функцию в стек можно записав в переменную? И тогда получится что функция выполняется из стека? Если да, то тогда такой вопрос. Насколько я понял все 4 сегмента DS CS SS FS(вот этот мне незнаком если несложно расскажите) адерсуют один и тот же дескриптор, разница только в начально адресе, тоесть по сути они имеют одно и тоже адресное пространство разница в возможностях использования этих данны. DS только данные READ_WRITE, CS только EXECUTE а вот SS и READ_WRITE и EXECUTE сразу. Теперь сам вопрос, допустим я получил эффективный адрес функции пусть это будет 00200000, сегмент стека начинается с нуля, сегмент данных с адреса 00100000 по 00400000 ну а дальше вроде бы идет сегмент кода. Сам вопрос. Вот могу я скажем взять и переписать кусок кода в стек, и выполнить его операцией call [SS+00010001] или что то в этом роде. И еще такой вопрос, если допустим я вызову такую команду call [SS+00200000] это ведь по идее должно работать или все же там есть какие  то ограничения на пороги адресации, ведь по идее это должно выглядеть как обращение к памяти кода но через стек. Меня это интересует со стороны модификации кода. Заранее благодарен и прошу прощения за столько  вопросов.

Задам еще последний вопрос. Где можно найти нормальную таблицу оппкодов, всякие MMX SSE итд меня мало интересуют. Те что на васме, распечатке не поддаются.
Чем больше я узнаю, тем больше чувствую себя дураком...

βεερ_βooρ

Цитата: Ivan_32 від 12 Лютий 2009, 05:56:14
Как можно получить адрес конца функции? У меня вот пока такой вариант назрел:
void foo()
{
  _asm
    {
     mov EndAddr,EIP+1
    }
}
Плохое решение. Впрочем ничего путного лучше в 6 утра я сейчас придумать не могу, мог лишь объяснить почему это работать не будет:
Цитата: Ivan_32 від 12 Лютий 2009, 05:56:14
Правда я не совсем не понимаю что лежит в EIP в этот самый момент, адрес этой же инструкции, адрес следущей инструкции или адерс предыдущей инструкции. Как это происходит?
Не EIP указывает на текущию команду как часто думают. На текущию команду укзыает CS:EIP, где EIP всего лишь смещение с начала сегмента кода, на который указывает CS. После выполнения коанды процессор увеличивает EIP на необходимую величину. А на 1 он его увеличит только если исходная комнда перед этим занимала 1 байт(например nop) Поэтому +1 не саботает. Тут нужнодругое магическое "число"(навскидку опкод 1байт, адрес переменной 4 байта, регистр 1 байт, смещение 1 байт => команда будет занимать ~7 байт.  )

Цитата: Ivan_32 від 12 Лютий 2009, 05:56:14
Да кстати такой еще вопрос. Поместить функцию в стек можно записав в переменную? И тогда получится что функция выполняется из стека?
Не понял суть вопроса. Стек - это область памяти. А в фон Неймановской архитектуре в памяти может быть строго говоря все что угодно - и данные и программа. тут главное не спутать ^_^
Цитата: Ivan_32 від 12 Лютий 2009, 05:56:14
Если да, то тогда такой вопрос. Насколько я понял все 4 сегмента DS CS SS FS(вот этот мне незнаком если несложно расскажите) адерсуют один и тот же дескриптор, разница только в начально адресе, тоесть по сути они имеют одно и тоже адресное пространство разница в возможностях использования этих данны. DS только данные READ_WRITE, CS только EXECUTE а вот SS и READ_WRITE и EXECUTE сразу. Теперь сам вопрос, допустим я получил эффективный адрес функции пусть это будет 00200000, сегмент стека начинается с нуля, сегмент данных с адреса 00100000 по 00400000 ну а дальше вроде бы идет сегмент кода. Сам вопрос. Вот могу я скажем взять и переписать кусок кода в стек, и выполнить его операцией call [SS+00010001] или что то в этом роде. И еще такой вопрос, если допустим я вызову такую команду call [SS+00200000] это ведь по идее должно работать или все же там есть какие  то ограничения на пороги адресации, ведь по идее это должно выглядеть как обращение к памяти кода но через стек. Меня это интересует со стороны модификации кода. Заранее благодарен и прошу прощения за столько  вопросов.
Иду спать, впрос сложный, отвечу позже.
Цитата: Ivan_32 від 12 Лютий 2009, 05:56:14
Задам еще последний вопрос. Где можно найти нормальную таблицу оппкодов, всякие MMX SSE итд меня мало интересуют. Те что на васме, распечатке не поддаются.
Хм, а маулы Интел и АМД?

C "неофциальных" источников гугль в певых же ссылках выдает:

http://ms-rem.dot-link.net/files/pentium.rar

Оно?
Fear is the path to the dark side. Fear leads to anger. Anger leads to hate. Hate leads to suffering.
All that's here is Fear! Suppression! Betrayal! Despair! Contempt! Regret! Sadness! Anguish! Madness! And Pain, right?

Ivan_32

#588
ЦитатаТут нужнодругое магическое "число"(навскидку опкод 1байт, адрес переменной 4 байта, регистр 1 байт, смещение 1 байт => команда будет занимать ~7 байт.  )
А что это за таинственный байт со смещением? По идее ведь так:
mov  var, eax   
1b     4b    1b

А что же за смещение тогда? Или это как раз то число которое прибавляется к EIP?
типа: 1b + 4b+ 1b=6b + 1b завершающий , содержит длину команды?

UPADATE:
Первая ссылка это просто список самых нужных команд, вторая не работает, третья - там таблица но проблема в том что там не указано что именно и куда вобщем не указывается регистр применик итд. Только размерность операндов, в общем случае это скажем так такая справка по допустимости операций.

NEW UPDATE:
Измерял размер функции вот этой функции:

desProc proc
   mov mBuff,al
desProc endp

Получилось 5 байт.
mov mBuff,eax 
тоже 5 байт.
Следовательно получается что байта для регистра нет как и байта с длиной команды.
Чем больше я узнаю, тем больше чувствую себя дураком...

βεερ_βooρ

Цитата: Ivan_32 від 12 Лютий 2009, 05:56:14
Насколько я понял все 4 сегмента DS CS SS FS(вот этот мне незнаком если несложно расскажите)
Изначально было 4 сгментных регистра: CS, DS, SS, ES
CS указывал на сегмент кода, DS -данных, SS - стек. ES -назывался Extended Segment. Он мог указывать ...куда угодно как и остальные сегментные регистры :) Поскольку размер сегмента был ограничен 64Кб, то ES указывал на какой-то еще сегмент данных. Например на видеопамять и т.д. Потом были добавлены регистры FS и GS. После того кк на х86 появиась возможность использовать flat-модель памяти необходимость в дополнительных сегментных регистрах отпала. Их теперь насколько я помню в основном юзают виртуализаторы.
Цитата: Ivan_32 від 12 Лютий 2009, 05:56:14
адерсуют один и тот же дескриптор,
Найн, найн, найн! В них помещают разные селекторы(дескриптор в 16 бит явно не везет ;)), аресующие разные дескрипторы в таблице GDTR! Ну а какие именно зависит от ОС. Но их оычно не очень много - современные ОС почтицеликом опираются на страничную адесцию при работе с памятью. Например в линуксе реально используются 4 дескриптора 2 для кода юзерспейс/ядра и 2 для данных. Все остальне уже сугубо служебны(LDT, TSS для переключения контекста, для поддержки биоса и т.д.):

/*
* The layout of the per-CPU GDT under Linux:
*
*   0 - null
*   1 - reserved
*   2 - reserved
*   3 - reserved
*
*   4 - unused                 <==== new cacheline
*   5 - unused
*
*  ------- start of TLS (Thread-Local Storage) segments:
*
*   6 - TLS segment #1                 [ glibc's TLS segment ]
*   7 - TLS segment #2                 [ Wine's %fs Win32 segment ]
*   8 - TLS segment #3
*   9 - reserved
*  10 - reserved
*  11 - reserved
*
*  ------- start of kernel segments:
*
*  12 - kernel code segment            <==== new cacheline
*  13 - kernel data segment
*  14 - default user CS
*  15 - default user DS
*  16 - TSS
*  17 - LDT
*  18 - PNPBIOS support (16->32 gate)
*  19 - PNPBIOS support
*  20 - PNPBIOS support
*  21 - PNPBIOS support
*  22 - PNPBIOS support
*  23 - APM BIOS support
*  24 - APM BIOS support
*  25 - APM BIOS support
*
*  26 - ESPFIX small SS
*  27 - per-cpu                        [ offset to per-cpu data area ]
*  28 - unused
*  29 - unused
*  30 - unused
*  31 - TSS for double fault handler
*/


Цитата: Ivan_32 від 12 Лютий 2009, 05:56:14
разница только в начально адресе,
Начальный адрес везде 0, конечный - 4Гб. Зачем мелочится? ^_^
Цитата: Ivan_32 від 12 Лютий 2009, 05:56:14
тоесть по сути они имеют одно и тоже адресное пространство разница в возможностях использования этих данны. DS только данные READ_WRITE, CS только EXECUTE а вот SS и READ_WRITE и EXECUTE сразу.
Да, сегменты кода и данных отличаются только правами.
Цитата: Ivan_32 від 12 Лютий 2009, 05:56:14
Теперь сам вопрос, допустим я получил эффективный адрес функции пусть это будет 00200000, сегмент стека начинается с нуля, сегмент данных с адреса 00100000 по 00400000 ну а дальше вроде бы идет сегмент кода.
Ну предположим, хотялогически все сегменты будут начинатся с  и заканчиваться на 4Гб. А как это в памят будет распологаться - уже не твоя проблема ;)
Цитата: Ivan_32 від 12 Лютий 2009, 05:56:14
Сам вопрос. Вот могу я скажем взять и переписать кусок кода в стек, и выполнить его операцией call [SS+00010001] или что то в этом роде. И еще такой вопрос, если допустим я вызову такую команду call [SS+00200000] это ведь по идее должно работать или все же там есть какие  то ограничения на пороги адресации, ведь по идее это должно выглядеть как обращение к памяти кода но через стек. Меня это интересует со стороны модификации кода.
Во-первых SS+00010001 - это что за безобразие? К сегментному регистру не добавляют смещение вручную! Регистр указывает на сегмент, а ты указывешь смещение с начала. Т.е. SS:<addr>
Во-вторых дался тебе тот стек. Он кстати может быть и неисполняймым.
Вот посмотри как делают полиморфные вирусы:
http://wasm.ru/article.php?article=vgw09
http://wasm.ru/article.php?article=1006009

Цитата: Ivan_32 від 12 Лютий 2009, 07:32:44

А что это за таинственный байт со смещением? По идее ведь так:
mov  var, eax   
1b     4b    1b

А что же за смещение тогда? Или это как раз то число которое прибавляется к EIP?
Ну должна же прибавка где-то хранится :)
Цитата: Ivan_32 від 12 Лютий 2009, 07:32:44
Получилось 5 байт.
mov mBuff,eax 
тоже 5 байт.
Следовательно получается что байта для регистра нет как и байта с длиной команды.
Подсчитай длину инструкции
mov mBuff,[ebx +1]

Fear is the path to the dark side. Fear leads to anger. Anger leads to hate. Hate leads to suffering.
All that's here is Fear! Suppression! Betrayal! Despair! Contempt! Regret! Sadness! Anguish! Madness! And Pain, right?

Ivan_32

Вот мой тестовый полигон:
.586
.model flat,stdcall
option casemap:none

   include windows.inc
   include user32.inc
   include kernel32.inc
   include masm32.inc
   includelib masm32.lib
   includelib user32.lib
   includelib kernel32.lib
dwtoa proto :DWORD,:DWORD
desProc proto
.data
fLength dd 0
mBuff db 512 dup(0)
fName db "D:\Func.bin",0
.data?
ofn OFSTRUCT <>
hProcess HANDLE ?
hFile HFILE ?
.code
start:
xor eax,eax
mov eax,OFFSET desProc
xor ebx,ebx
mov ebx,OFFSET ended
sub ebx,eax
mov fLength,ebx

invoke GetCurrentProcess
mov hProcess,eax
invoke ReadProcessMemory,hProcess,addr desProc,addr mBuff,fLength,0
invoke OpenFile,addr fName,addr ofn,OF_CREATE or OF_READWRITE
mov hFile,eax
invoke WriteFile,hFile,addr mBuff,fLength,0,0
invoke MessageBox,0,0,0,0
invoke ExitProcess,0
desProc proc
mov edx,0
mov ebx,0FFFFFFFFh
ret
desProc endp
ended:
end start

А вот содержание файла, в который оно записало функцию:
BA 00 00 00 00 BB FF FF FF FF C3

Вобщем проблема в том что после выполнения WriteFile(или во время) программа падает. Запись происходит вполне корректно.

mov mBuff,[ebx+1] это же mem to mem , вроде как не поддерживается ни одним x86 процессором.
Чем больше я узнаю, тем больше чувствую себя дураком...

βεερ_βooρ

Цитата: Ivan_32 від 13 Лютий 2009, 07:40:04
Вот мой тестовый полигон:
.586
.model flat,stdcall
option casemap:none

   include windows.inc
   include user32.inc
   include kernel32.inc
   include masm32.inc
   includelib masm32.lib
   includelib user32.lib
   includelib kernel32.lib
dwtoa proto :DWORD,:DWORD
desProc proto
.data
fLength dd 0
mBuff db 512 dup(0)
fName db "D:\Func.bin",0
.data?
ofn OFSTRUCT <>
hProcess HANDLE ?
hFile HFILE ?
.code
start:
xor eax,eax
mov eax,OFFSET desProc
xor ebx,ebx
mov ebx,OFFSET ended
sub ebx,eax
mov fLength,ebx

invoke GetCurrentProcess
mov hProcess,eax
invoke ReadProcessMemory,hProcess,addr desProc,addr mBuff,fLength,0
invoke OpenFile,addr fName,addr ofn,OF_CREATE or OF_READWRITE
mov hFile,eax
invoke WriteFile,hFile,addr mBuff,fLength,0,0
invoke MessageBox,0,0,0,0
invoke ExitProcess,0
desProc proc
mov edx,0
mov ebx,0FFFFFFFFh
ret
desProc endp
ended:
end start

А вот содержание файла, в который оно записало функцию:
BA 00 00 00 00 BB FF FF FF FF C3

Вобщем проблема в том что после выполнения WriteFile(или во время) программа падает. Запись происходит вполне корректно.
К чему такие сложности?  ???
Просто возьми и скомпилируй в raw binary:
use32
mov edx,0
mov ebx,0FFFFFFFFh
ret

bash-3.1$ fasm 1.asm
flat assembler  version 1.67.23  (16384 kilobytes memory)
1 passes, 11 bytes.
bash-3.1$ hexdump -C 1.bin
00000000  ba 00 00 00 00 bb ff ff  ff ff c3                 |╨....╩ЪЪЪЪц|
0000000b

Цитата: Ivan_32 від 13 Лютий 2009, 07:40:04
mov mBuff,[ebx+1] это же mem to mem , вроде как не поддерживается ни одним x86 процессором.
Извиняюсь, провтыкал :-[
Fear is the path to the dark side. Fear leads to anger. Anger leads to hate. Hate leads to suffering.
All that's here is Fear! Suppression! Betrayal! Despair! Contempt! Regret! Sadness! Anguish! Madness! And Pain, right?

firefire

ЦитатаЩасливі п'ятірки. На світі існують люди, які вважають п'ятірку щасливим числом. Вони кидають декілька гральних кісток, і якщо п'ятірка випаде більше ніж в одній п'ятій частині кісток, то день вважається щасливим. Кидається dice однакових кісток, кожна з яких має sides сторін. Обчислити ймовірність того, що день буде щасливим. Ймовірність випадання п'ятірки при киданні кістки з sides сторонами дорівнює 1 / sides.
Кожний вхідний рядок містить два числа: dice та sides
(1 ≤ dice ≤ 20, 5 ≤ sides ≤ 10).

Можете ли кто-то помочь объяснить теорию вероятности? Я просто буду учить только со следующей недели. А задачку эту надо решить  :%)

немой

Цитата: firefire від 14 Лютий 2009, 06:30:31
Кожний вхідний рядок містить два числа: dice та sides
(1 ≤ dice ≤ 20, 5 ≤ sides ≤ 10).

Можете ли кто-то помочь объяснить теорию вероятности? Я просто буду учить только со следующей недели. А задачку эту надо решить  :%)
ЦитатаПриклад входу
Приклад виходу
1 6       0.1666
5 6       0.1962
20 10    0.0431
наверно так:
кубик бросается 1, граней 6. 1/5 кубика = 1 кубик, вероятность 1/6;
кубиков 5 бросается, граней 6. 1/5 всех кубиков = 1, не менее 1 кубика должно быть с 5й на гране = 1 кубик с 5й, 2 кубика с 5й, 3 кубика с 5й, .... , 5 кубиков с 5й = 1/6 + 1/6*1/6+1/6*1/6*1/6+...+(1/6)^5.
по идее так, перепроверь для второго и третьего случая этим способом, я не считал, только прикинул.

firefire

Цитата: немой від 14 Лютий 2009, 07:58:36
наверно так:
кубик бросается 1, граней 6. 1/5 кубика = 1 кубик, вероятность 1/6;
кубиков 5 бросается, граней 6. 1/5 всех кубиков = 1, не менее 1 кубика должно быть с 5й на гране = 1 кубик с 5й, 2 кубика с 5й, 3 кубика с 5й, .... , 5 кубиков с 5й = 1/6 + 1/6*1/6+1/6*1/6*1/6+...+(1/6)^5.
по идее так, перепроверь для второго и третьего случая этим способом, я не считал, только прикинул.
От куда ты знаешь что дальше есть "приклады"?  :)

βεερ_βooρ

#595
Цитата: firefire від 14 Лютий 2009, 06:30:31
Можете ли кто-то помочь объяснить теорию вероятности? Я просто буду учить только со следующей недели. А задачку эту надо решить  :%)
Объяснить не сможем. Это быстро не делается. Но задачку решить можно. Она в одну формулу.
На самостоятельное изучение:


Множество элементарных исходов - это выборка с возвращением, без учета порядка.
Пусть даны к-во сторон кости s и число костей d
Мощность множества элементарных исходов = биномиальный коефициент из s+d-1 по d:

Мощность м-ва удачных исходов считаем аналогично, только мы фиксируем ceil(d/5)*[1] исходов - там должны стоять пятерки. Т.е. у нас есть выборка с возвращением без учета порядка из s + (d-ceil(d/5)) -1 по d-ceil(d/5) :


Далее используй классическое определение вероятности:


[1] Ceil(потолок) - ближайшее целое число, не меньше данного. Пр: ceil(1.5)=2; ceil(pi)=4, ceil(1/5)=1
Fear is the path to the dark side. Fear leads to anger. Anger leads to hate. Hate leads to suffering.
All that's here is Fear! Suppression! Betrayal! Despair! Contempt! Regret! Sadness! Anguish! Madness! And Pain, right?

Ivan_32

#596
.586
.model flat,stdcall
option casemap:none

   include windows.inc
   include user32.inc
   include kernel32.inc
   include masm32.inc
   includelib masm32.lib
   includelib user32.lib
   includelib kernel32.lib
   dwtoa proto :DWORD,:DWORD
.data
fAddr DD 0
fLen DD 0
.data?
hBuff0 HANDLE ?
hBuff1 HANDLE ?
pBuff0 DWORD ?
pBuff1 DWORD ?
hProcess HANDLE ?
mbi MEMORY_BASIC_INFORMATION <>
.code
start:
INVOKE GlobalAlloc,GMEM_MOVEABLE OR GMEM_ZEROINIT,512
MOV hBuff0,EAX
INVOKE GlobalAlloc,GMEM_MOVEABLE OR GMEM_ZEROINIT,1024
MOV hBuff1,EAX

INVOKE GlobalLock,hBuff0
MOV pBuff0,EAX
INVOKE GlobalLock,hBuff1
MOV pBuff1,EAX


MOV EAX,OFFSET Func
MOV fAddr,EAX
MOV EBX,OFFSET FuncEND
SUB EBX,EAX
MOV fLen,EBX
INVOKE GetCurrentProcess
MOV hProcess,EAX
INVOKE ReadProcessMemory,hProcess,fAddr,pBuff0,fLen,0


XOR EAX,EAX
XOR EBX,EBX
XOR ECX,ECX
.WHILE ECX<512
PUSHAD
XOR EAX,EAX

MOV AH,BYTE PTR[pBuff0+ECX]
SHR AH,4
.IF AH<10
ADD AH,30h
.ELSEIF AH>9
ADD AH,37h
.ENDIF
MOV BYTE PTR[pBuff1+EBX],AH

MOV AH,BYTE PTR[pBuff0+ECX]
AND AH,00001111b
.IF AH<10
ADD AH,30h
.ELSEIF AH>9
ADD AH,37h
.ENDIF
MOV BYTE PTR[pBuff1+EBX+1],AH

POPAD
INC EBX
INC EBX
INC ECX
.ENDW
INVOKE GlobalUnlock,addr hBuff1
INVOKE MessageBox,0,ADDR pBuff1,0,0
INVOKE ExitProcess,0

Func PROC
RET
DB 511 DUP(0)
Func ENDP
FuncEND:
end start

Пример выполнения:

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

Не знаю что делать, может быть у меня проблемы с железом? Память у меня сейчас при тестах разогнана до 900Mhz 5-5-5-15 c 800 Mhz 5-5-5-18. Но этот глюк с тройками и раньше был, когда тайминги были 5-6-6-21.
Чем больше я узнаю, тем больше чувствую себя дураком...

βεερ_βooρ

#597
Цитата: Ivan_32 від 16 Лютий 2009, 20:29:03
Не знаю что делать, может быть у меня проблемы с железом? Память у меня сейчас при тестах разогнана до 900Mhz 5-5-5-15 c 800 Mhz 5-5-5-18. Но этот глюк с тройками и раньше был, когда тайминги были 5-6-6-21.
Мне сейчас накладно и неудобно компилить и дебажить этот код под виндоус, но одно могу сказать определенно: Если бы у тебя были настолько большие проблемы с железом, то ты бы об этом не срашивал. Система была бы настолко нестабильна, что даже ОС агрузить не удалось бы.

Цитата: Ivan_32 від 16 Лютий 2009, 20:29:03
Как видно из кода, в меседж боксе должны быть нули.
На чем основана уверенность?
Fear is the path to the dark side. Fear leads to anger. Anger leads to hate. Hate leads to suffering.
All that's here is Fear! Suppression! Betrayal! Despair! Contempt! Regret! Sadness! Anguish! Madness! And Pain, right?

Ivan_32

pBuff0 - выделенная и инициализированная нулями память в которую записывается функция в которой 511 из 512 байт нули. Первый байт это C3. Ну не могут там быть не нули.. функция перевода работает корректно - ее уже 100 раз проверял в других программах. Я не понимаю как может ни с того ни с сего ноль(30h) превратится в  3(33h).
Чем больше я узнаю, тем больше чувствую себя дураком...

Andrii

Підскажіть, будь ласка, код, який запамятовує пароль і логін, введений один раз, щоб потім його повторно не вводити!. Це, здається, кукі робить.