-
Постов
410 -
Зарегистрирован
-
Посещение
-
Победитель дней
16
Тип контента
Профили
Форумы
Загрузки
Блоги
Весь контент Antonshka
-
Такой?
-
А идея отличная у тебя, если бы не ассинхронизация, я бы её и использовал.
-
Верно, но я не могу использовать это место. Не могу использовать этот VCRUNTIME140 поток. Мне нужно только обезвредить, так сказать, этот Repe movsb, на время, пока я собственным потоком записываю данные в адреса. Мой собственный поток это не Repe movsb или подобное что-то. Мой собственный поток это будет просто обычная инструкция MOV и переменная счетчик.
-
Запись будет по флагу. Например флаг равен 1, идет запись ранее сохраненных значений в адреса. Запись продолжается до тех пор пока, либо флаг не станет равным 0, либо пока не настанет конец файла на диске.
-
Вот код, он и пишет и читает.
-
В RSI как я понял всегда находится источник, откуда копируется. В RDI приемник, куда. Поэтому если писать этим же потоком в котором находится Repe movsb в нужные мне адрес, тогда правильно у тебя было в первом сообщении. mov byte ptr [rdi+5],#66. Но как я написал во втором сообщении, я теперь не могу использовать поток в котором находится Repe movsb. Я хочу создать свой собственный поток через CreateThread, он то и будет писать в нужные мне адреса. Просто в то время когда мой поток пишет, тогда Repe movsb должна пропускать эти некоторые адреса.
-
Да, отличная идея. В этой игре, когда Repe movsb пишет в нужные мне адреса, тогда RSI это источник, а RDI приемник. Когда эта инструкция читает из нужных мне адресов. тогда RSI это бывший RDI, а RDI уже новый приемник (не бывший RSI). Можно, как ты говоришь, перед тем как эта инструкция начнет считывание блока, записать потоком в котором находится инструкция Repe movsb в нужные мне адреса нужные мне значения. Все равно ведь их ничто не изменить, до тех пор пока эта же инструкция не станет записывающей. Но я сейчас подумал, оказалось что мне немного не выгодно использовать инструкцию Repe movsb для манипуляций над значениями нужных мне адресов. Все дело в том, что мод который я делаю должен сохранять на диск значения в этих некоторых адресах. А затем, по надобности, этот же мод должен записывать обратно полученное ранее. А так как инструкция Repe movsb может работать в разное время с разной скоростью, то может получиться некоторая ассинхронизация, эффект мода будет как бы уже не тот. Я хочу использовать для записи значений в эти некоторые адреса собственный поток. И вот задача теперь такая, в то время когда мой собственный поток пишет данные в адреса, инструкция Repe movsb должна пропускать запись только в эти некоторые адреса.
-
Привет всем. Я к вам с интересной задачей. Раньше с таким не сталкивался. В одной игре характеристики машины находятся в одном блоке памяти. Этот блок памяти контролируется только одной инструкцией Repe movsb, она и читает, она и записывает. Мне нужно взять под контроль всего лишь несколько разных адресов этого копируемого блока. Как мне быть? У меня есть одна идея, но я не знаю насколько она хороша, я её еще даже и не опробовал. Может ваши будут лучше, и я их применю. Или вы мою улучшите. Моя идея такая, может быть 1 - заменить значение RCX перед копированием на такое, чтобы скопировался блок только до нужного мне адреса, 2 - сделать какие-нибудь манипуляции со значением нужного мне адреса, ради чего собственно это всё 3 - к RSI и RDI прибавить размер уже скопированного блока и прибавить размер нужного мне адреса (4 байта например) 4 - записать в RCX размер оставшегося и еще не скопированного блока минус размер нужного адреса 5 - снова вызвать копирование. И так для всех нужных мне адресов. Причем расположив все процедуры копирования остатков блоков в порядке нужных мне адресов.
-
У меня из опыта такие мысли по этому поводу. У каждой машины есть свои технические характеристики. Например вес, инерция, аэродинамика, мощность двигателя, количество передач, вес колеса. Все это и много другое определяет поведение каждого автомобиля, в частности его ускорение и максимальную скорость. Изменив параметры изменим скорость. Есть также инструкция кода, которая сбрасывает значения Velocity до максимально разрешенных. Занопив инструкцию снимем ограничение.
-
Я изучаю с++ уже второй месяц, но написать такой программы как у тебя пока не могу. Даже и не имею представления о том как это сделать. Может это от того, что я решил сперва освоить самые основы. На данный момент мною прочитана книга Лафоре, и начата книга "с++ Primer" (~300 страниц из 1124). Книга Лафоре имеет замечательную постепенность преподавания материала, забегания вперед практически нет. Читается на одном дыхании. "с++ Primer" в этом плане не такова, но её материал более концентрирован, нет отклонений ни направо ни налево, все строго и без единого лишнего слова. "с++ Primer" нужно читать после Лафоре.
-
Привет, меня заинтересовал тот факт, что приложение написано на с++. Расскажи о своем пути изучения этого языка. - как давно началось твоё изучение этого языка? - сколько материала было прочитано, сколько книг? - обучаешься в училище? - посоветуешь книги по с++? - какая часть языка была самая труднопонимаемая? Также, отчего 64 битная версия не выйдет в ближайшее время?
-
А, всё, разобрался. Объявление переменной не пропускается. Так как case не создает здесь свою область, но сам он (case) находится в области switch, то значит и это объявление переменной также находится в области switch и не относится к case. Значит инициализации и объявления переменных всех case-s (case-s не имеющих свою собственную область) также находятся в области switch, в начале. А инициализировать переменную в последней метки case оператора switch, допускается потому, что эта метка не может быть пропущена (хотя в тоже время может и не выполниться). int value = 123; switch (value) { case 1: case 2: int ival_2 = 8; // допускается компилятором. Не однозначности нет }
-
О, спасибо тебе, как же я долго искал этот ответ. Спасибо всем кто откликнулся. Итог сообщенных мне, ваших знаний - переменные объявляются и переменные инициализируются во время сборки - переменные во время сборки распределяются на две секции: секция для инициализированных, и секция для не инициализированных. - при распределении переменных во время сборки на секции не допускается неоднозначность, то есть не допускается в коде возможный пропуск выражения инициализации переменной. Компилятор в таком случае не будет точно знать в какую секцию поместить переменную, так как она может быть и инициализированной, (в случае если не будет её пропуска) и не инициализированной (в случае её пропуска). int value = 0; Switch (value) { case 1: // возможен пропуск int v1 = 123; // неоднозначная ситуация, не допускается. Компилятор придет в замешательство во время сборки, пытаясь определить секцию int v2; //допускается такое объявление, так как оно выполняется всегда, во время сборки, независимо от возможного пропуска int v3; case 2: // возможен пропуск int v4 = 123; // неоднозначная ситуация, не допускается. Компилятор придет в замешательство во время сборки, пытаясь определить секцию int v5; //допускается такое объявление, так как оно выполняется всегда, во время сборки, независимо от возможного пропуска v2 = 789; // допускается присвоение, так как v2 объявлена выше/раньше, во время сборки int v3; // не допускается, так как в одной области видимости (область Switch в данном случае) нельзя иметь переменные с одинаковым именем case 3: // пропуска быть не может, так как это последняя метка оператора Switch, неоднозначности нет int v6 = 123; //допускается, так как копмилятор точно уверен, в какую секцию определить переменную }
-
Начало Switch исполняется всегда? Не зависимо от значения PARAM в выражении Switch(PARAM) ? Если исполняется всегда, и если переменные находятся не в case, но в начале Switch, то почему не выполняется инициализация переменной в этом начале, так же, как выполняется объявление? Почему в начале это выполняется int someval; а это нет int someval = 12345; Подскажи пожалуйста.
-
Спасибо, просмотрел, это все мне уже известно, но почему-то от этого я все равно не понимаю решения вопроса темы. Вот какие мои мысли пока что в коде ниже, Switch имеет свою область видимости А, и int ival_1 = 1; имеет свою область видимости Б. Теперь ival_1 невидима в области А совсем. Это значит, что и проблемы из-за её пропуска также теперь нет совсем. Switch(value) { // Область А начало case 1: { //Область Б начало int ival_1 = 1; } //Область Б конец } // Область А конец Если это так, то это мне теперь понятно. Остались непонятны другие вопросы описанные в начале темы. Наример
-
Switch(выражение) { область видимости для Switch } Ты не эту область видимости имел ввиду? Если не трудно, объясни поподробнее то, что ты знаешь об этом вопросе. Я перерыл интернет, был на сайтах, на оф. сайтах, в разных книгах, - нигде нет понятного для меня ответа, но везде говорят как-бы на другом, понятном только для них самих языке.
-
Привет всем, знающие люди, помогите понять причину следующей ситуации, отнявшей у меня несколько часов безрезультатного интернет поиска (результаты были, но я из них ничего не понял) Не понятно почему в case 1 нельзя писать int ival_1 = 1; но можно писать int ival_1; Объяснение из книги, - "в случае если value не будет равно 1, то будет пропущена метка case 1, следовательно и инициализация переменной ival_1 также будет пропущена." Но ведь если пропускается метка case 1, то тогда зачем и заботится об инициализации ival_1? Вот что более всего непонятно - почему в case 1, вместо int ival_1 = 1 допускается написать int ival_1; а затем использовать эту int ival_1 в case 2 (например ival_1 = 456), ведь согласно логике в случае пропуска метки case 1, переменная ival_1 в выражении ival_1 = 456 будет не объявлена прежде. - почему таким образом допускается писать код
-
В конце книги Лафоре есть ответы на некоторые его задачи. Есть ответ и на эту задачу. Вот (нерабочий) ответ, из оригинала книги Непонятно почему в этом скрипте вызывается конструктор базового класса из тела конструктора производного класса. @JustHack Понятно, но в списке инициализации нельзя выполнить какое-либо условие (а оно должно быть в этой задаче), потому видимо вызов конструктора базового класса и был перенесен в тело конструктора. В интернете нашел еще такое решение, вместо вызова конструктора else //not too long, String(s); использовать уже непосредственно саму функцию того конструктора else //not too long, strcpy_s(str, s);
-
Привет всем, кто-нибудь из вас сталкивался с ошибкой компилятора ""error C2082: переопределение формального параметра "pstr"? скрипт если вместо Pstring(const char pstr[]) { String(pstr); } записать Pstring(const char pstr[]) : String(pstr) { } то ошибки нет. Решение проблемы взятое из Microsoft Docs - В теле функции переопределен формальный параметр функции. Чтобы устранить эту ошибку, удалите повторное определение. void func(int i) { int i; // C2082 int ii; // OK } Никак не могу найти причину. Ведь я вызываю конструктор с одним параметром класса String, и передаю ему аргумент pstr. Как правильно вызвать конструктор String, из тела конструктора Pstring, передав ему при этом параметр pstr?
-
Благодарю @partoftheworlD, return усвоен. Реализация на Lua - тема не менее интересная. @MasterGH , как оказалось, в оригинале книги пирамида симметричная , и имеет такой вид X XXX XXXXX XXXXXXX с каждой новой строкой количество Х увеличивается на 2 порядка. с++ скрипт пирамиды
-
Спасибо, интересный способ. Единственное что мне пока не понятно - Функция calculate и оператор switch в определенной ситуации могут вернуть - return 0. Если calculate вернет 0, то условие "if (calculate(method, a, b, c, d))" - будет ложно, и сработает brear для цикла while (stop != 'n'), - этот момент понятен. Не понятно почему while (stop != 'n') зависит от этого возвращаемого нуля - "default: cout << "wrong answer" << endl; return 0;". Ведь в условии выполнения while только значение переменной stop. Или этот 0 возвращается для int main()? Если 0 для while , то верно ли то, что любой цикл, будь то for, while, do, можно завершить не только изменив условие цикла или выполнив break, но и вернув ему (циклу) 0? А значит можно записать код так? switch (stop) { case 'y': continue; case 'n': return 0; //case 'n': break; default: cout << "wrong answer" << endl; return 0; } А если 0 из "default: cout << "wrong answer" << endl; return 0;" для int main(), то значит ли это то, что return 0 минует все множество вложенных циклов, и всегда предназначен для текущей конкретной фунции (для возврата текущей функцией в вызывающий её оператор этого нуля (или может не 0, а чего другого). Если при выполнении функции случится выполниться методу "return чего либо", например в середине функции, то значит ли это то, что функция на этом самом месте немедленно прекратит свою работу, вернув результат, несмотря на то, что другая часть/части этой функции также желали быть исполненными? Ответ на эти вопросы я возможно ещё встречу в книге, но мне уже сейчас хочется его узнать. P.S. если ввести не 'y' и не 'n' программа завершится. Но что если нужно снова спросить о желании расчёта? Ведь GOTO я и использовал для этого.
-
Понятно, буду знать. Что если использовать "goto" в такой ситуации? Этот скрипт на задание из книги. Первое что мне пришло в голову, это использовать goto для прыжка назад.