Отвратительная система охлаждения. Мало того, что выхлоп справа (хоть я и левша, я держу мышку правой рукой… для кого это сделали — не ясно). Так еще и процессор перегревается.
Спасибо за обзор, в котором магазин не стесняется объективно критиковать продукт.
> Не стоит прятать части сайта только потому, что они не помещаются на экране мобильного устройства.
Правильно. Его надо не убирать вообще, но перемещать/прятать (во вкладки, различные выезжающие меню, каты), что бы он не мешал восприятию основного контента.
Взять конкретно эту страницу — блок «Похожие посты» справа вверху совсем не обязательно лицезреть на малюсеньких экранах смартфонов. Его необходимо сделать либо внизу, либо «выезжающим по клику»
Тут вообще черти что. Тень должна быть и внутри корпуса (циферблата?). Если предположить, что он выпуклый (т. е. голубая поверхность внутри находится выше, то не должно быть тени на его окантовке.
1.
Правильно сказать так: В большинстве инструкций, в т. ч. использующих 2 операнда хотя бы один из них должен являться регистром. В других случаях операнд может быть памятью или указан непосредственно в инструкции, но вариант с регистром всегда исполняется заметно быстрее.
Такая формулировка совсем не сложная, но намного более корректная. Это в целом относится ко всей статье — можно излагать просто и понятно, но при этом не допускать таких неточностей.
> Вам, как профессионалу
К слову, я вообще не профессионал, и моя деятельность не имеет к ИТ никакого отношения. Впрочем, в юношестве, я разрабатывал один проект, и, из-за юношеского-же максимализма делал его на АСМ. Это было адово, когда файл разросся до 10к строк кода. Я использовал только переходы (аналог на C — go to), и попробуйте представить, какой там был спагетти код. И конечно-же (кто-бы мог подумать?) поддерживать программу стало сложнее. Нестройные ряды пользователей до сих пор поминают меня незлым тихим словом и лелеют надежду, что я выпушу исправления…
7. Да, OllyDbg — только под windows, как уже и написали ниже. Но она действительно крутая.
Если 0 идет как imm — то он читается вместе с инструкцией. Хотя кто его знает, тут уже сложный процесс. И вот в чем беда низкоуровневого кодинга — с точки зрения быстродействия мы вряд-ли что-то выиграем, оптимизирую то, о чем мы говорим.
1.
> нет опкодов (почти), которые бы например позволяли сложить два числа, которые находятся в памяти
В x86-32 для инструкции ADD допустимы следующие операнды: reg,reg / mem,reg / reg,mem / reg,imm / mem,imm / accum,imm. Вариант mem,mem не предусмотрен, т. е. что бы сложить две переменные — хотя бы одну надо загрузить в регистр.
2.
> Очевидно имеется ввиду адрес участка памяти, который там хранится, и если его не менять, то традиционно он выше у первого.
Бла-бла-бла описание вариантов работы с процедурами, бла-бла-бла описание работы со стеком и локальными переменными, бла-бла-бла большинство компиляторов так и поступают. И Вывод: при таком использовании действительно, BP будет иметь большее значение, чем SP. Вот с этим конечно нельзя не согласиться. С другой стороны компилятор X вообще делает все по другому, и уже такое утверждение не справедливо. Просто нельзя так обобщать.
3.
> Я так понимаю, вот это самое несуществующее соглашение. Возможно стоит исправить на «Соглашение о вызовах для архитектуры x86»
По ссылке «This article describes the calling conventions used on the x86 architecture». Тут я действительно придрался к формулировке, но в самой архитектуре как таковой соглашения и нет.
4.
> Здесь раздел Scope однозначно нам все объясняет…
С точки зрения скомпилированного кода между глобальной и статичной переменной не будет никакой разницы, но она будет между статичной и локальной. В теме ведь обсуждается АСМ?
5.
> Что Вы подразумеваете под «нет инструкции». Если воздействовать на этот участок памяти руками, то смотрите ответ выше, касающейся регистров.
В Ъ АСМ нет понятия переменной. Есть понятие данных (памяти) и меток/аддрессов, по которым осуществляется доступ. Далее, стек — точно такая же память, и если посмотреть, как он работает, то просто станет очевидным, и почему перезаписываются локальные переменные, и почему в них может содержаться мусор, и почему не меняются сами собой статичные переменные. И про память, и про секцию инициализированных данных станет все ясно.
6.
> Также Вы можете обратить внимание, что GDB устанавливает значения для наших переменных, и так же как и во всех переменных в GDB, перед их именем стоит префикс $, в то время как префикс % используется в ассемблере от AT&T.
В GDB перед именем переменных идет символ $, а в синтаксисе AT&T — символ %
7.
> Что касается OllyDbg… Я совсем недавно познакомился с GDB, и скажу честно, если бы увидел сразу такого монстра, как OllyDbg, то не стал бы продолжать.
Вот и зря. В ней все просто, слева листинг кода, справа — регистры, внизу память и стек. И все это можно запускать пошагово, и видеть, как после какой инструкции изменилось состояние, вот например описание www.cracklab.ru/faq/OllyDbg
Просто пару скриншотов OllyDbg, что-бы таки было понятно, что с чем сравнивают. Тут тебе и стек, и весь листинг, и регистры, и память, и точки остановки, и еще куча всего, что способствует.
> Скорость доступа к регистрам очень высокая и именно из-за этого в них часто хранятся операнды арифметических и логических операций.
Нет, просто нет опкодов (почти), которые бы например позволяли сложить два числа, которые находятся в памяти.
> Регистр %rbp всегда имеет высшее значение нежели %rsp
Нет, регистр имеет то значение, которое в него поместили (или изменили соответствующими командами).
> Соглашение о вызовах, в архитектуре x86 гласит, что возвращаемые функцией значения хранятся в регистре %eax
Нет, в архитектуре x86 нет соглашения о вызовах, и его не может быть в архитектуре. В архитектуре есть набор команд, которым можно реализовать вызовы процедуры. Причем, возвращение значения в регистре EAX вообще ничем не обусловлено, с таким-же успехом его можно было-бы возвращать в EBX, участке памяти и на на стеке. С другой стороны, момент о типах вызовов и передаче аргументов вообще упущен в статье.
> Статические локальные переменные — это очень классная особенность С. В двух словах, они являются локальными переменными, которые инициализируются один раз и сохраняют свое значение между вызовами функции, в которой были объявлены.
Нет, они являются глобальными переменными, область видимости которых просто ограничена одной функцией (в отличии от локальных они не создаются при каждом входе в процедуру, и при рекурсии используется одна и та-же переменная).
> Не важно сколько раз будет вызываться наш генератор, переменная b всегда будет сохранять свое предыдущее значение. Все это потому, что она хранится вне стека и инициализируется, когда загрузчик помещает программу в память, а не по какому-то из наших машинных кодов.
Нет, она сохраняет свое значение потому, что нет инструкции, которая бы меняла данные, которые находятся по данному аддрессу (вне процедуры). Стек аддрессует точно такую же память, и к ней применимы все (почти) правила, которые и применимы к памяти, которая считается секцией данных (в семействе Windows, никогда не разбирая ядро других ОС). Впрочем, говорить об этом в статье без объяснения локальных переменных, вызовов процедур и прочего смысла нет.
И последнее:
> Также Вы можете обратить внимание, что GDB устанавливает значения для наших переменных, и так же как и во всех переменных в GDB, перед их именем стоит префикс $, в то время как префикс % используется в ассемблере от AT&T.
Спасибо за обзор, в котором магазин не стесняется объективно критиковать продукт.
Не понял. У меня Ctrl + или — меняют масштаб, не применяя правила для pixel ratio.
Правильно. Его надо не убирать вообще, но перемещать/прятать (во вкладки, различные выезжающие меню, каты), что бы он не мешал восприятию основного контента.
Взять конкретно эту страницу — блок «Похожие посты» справа вверху совсем не обязательно лицезреть на малюсеньких экранах смартфонов. Его необходимо сделать либо внизу, либо «выезжающим по клику»
Правильно сказать так: В большинстве инструкций, в т. ч. использующих 2 операнда хотя бы один из них должен являться регистром. В других случаях операнд может быть памятью или указан непосредственно в инструкции, но вариант с регистром всегда исполняется заметно быстрее.
Такая формулировка совсем не сложная, но намного более корректная. Это в целом относится ко всей статье — можно излагать просто и понятно, но при этом не допускать таких неточностей.
> Вам, как профессионалу
К слову, я вообще не профессионал, и моя деятельность не имеет к ИТ никакого отношения. Впрочем, в юношестве, я разрабатывал один проект, и, из-за юношеского-же максимализма делал его на АСМ. Это было адово, когда файл разросся до 10к строк кода. Я использовал только переходы (аналог на C — go to), и попробуйте представить, какой там был спагетти код. И конечно-же (кто-бы мог подумать?) поддерживать программу стало сложнее. Нестройные ряды пользователей до сих пор поминают меня незлым тихим словом и лелеют надежду, что я выпушу исправления…
7. Да, OllyDbg — только под windows, как уже и написали ниже. Но она действительно крутая.
Ну нет же. В статье говорится — используем регистры, потому что так быстрее. На самом деле по другому просто нельзя.
2. > На таком этапе читателю достаточно знать, что большинство компиляторов так поступают…
Вот именно, так поступает большинство компиляторов. А не «так было и будет всегда».
4. и 5. > а разбираемся мы в С, поэтому и оперируем понятиями С.
Мое мнение — что если хочется понять логику работы — то таки придется разбираться в АСМ, благо это не так сложно.
7. > Но чтобы ознакомиться на маленькой программке лучше все же GDB. Ввел простенькую команду — получил наглядный результат — осознал происходящее.
Я в свое время учился на Olly, и в действии она намного проще, чем кажется.
> нет опкодов (почти), которые бы например позволяли сложить два числа, которые находятся в памяти
В x86-32 для инструкции ADD допустимы следующие операнды: reg,reg / mem,reg / reg,mem / reg,imm / mem,imm / accum,imm. Вариант mem,mem не предусмотрен, т. е. что бы сложить две переменные — хотя бы одну надо загрузить в регистр.
2.
> Очевидно имеется ввиду адрес участка памяти, который там хранится, и если его не менять, то традиционно он выше у первого.
Бла-бла-бла описание вариантов работы с процедурами, бла-бла-бла описание работы со стеком и локальными переменными, бла-бла-бла большинство компиляторов так и поступают. И Вывод: при таком использовании действительно, BP будет иметь большее значение, чем SP. Вот с этим конечно нельзя не согласиться. С другой стороны компилятор X вообще делает все по другому, и уже такое утверждение не справедливо. Просто нельзя так обобщать.
3.
> Я так понимаю, вот это самое несуществующее соглашение. Возможно стоит исправить на «Соглашение о вызовах для архитектуры x86»
По ссылке «This article describes the calling conventions used on the x86 architecture». Тут я действительно придрался к формулировке, но в самой архитектуре как таковой соглашения и нет.
4.
> Здесь раздел Scope однозначно нам все объясняет…
С точки зрения скомпилированного кода между глобальной и статичной переменной не будет никакой разницы, но она будет между статичной и локальной. В теме ведь обсуждается АСМ?
5.
> Что Вы подразумеваете под «нет инструкции». Если воздействовать на этот участок памяти руками, то смотрите ответ выше, касающейся регистров.
В Ъ АСМ нет понятия переменной. Есть понятие данных (памяти) и меток/аддрессов, по которым осуществляется доступ. Далее, стек — точно такая же память, и если посмотреть, как он работает, то просто станет очевидным, и почему перезаписываются локальные переменные, и почему в них может содержаться мусор, и почему не меняются сами собой статичные переменные. И про память, и про секцию инициализированных данных станет все ясно.
6.
> Также Вы можете обратить внимание, что GDB устанавливает значения для наших переменных, и так же как и во всех переменных в GDB, перед их именем стоит префикс $, в то время как префикс % используется в ассемблере от AT&T.
В GDB перед именем переменных идет символ $, а в синтаксисе AT&T — символ %
7.
> Что касается OllyDbg… Я совсем недавно познакомился с GDB, и скажу честно, если бы увидел сразу такого монстра, как OllyDbg, то не стал бы продолжать.
Вот и зря. В ней все просто, слева листинг кода, справа — регистры, внизу память и стек. И все это можно запускать пошагово, и видеть, как после какой инструкции изменилось состояние, вот например описание www.cracklab.ru/faq/OllyDbg
Нет, просто нет опкодов (почти), которые бы например позволяли сложить два числа, которые находятся в памяти.
> Регистр %rbp всегда имеет высшее значение нежели %rsp
Нет, регистр имеет то значение, которое в него поместили (или изменили соответствующими командами).
> Соглашение о вызовах, в архитектуре x86 гласит, что возвращаемые функцией значения хранятся в регистре %eax
Нет, в архитектуре x86 нет соглашения о вызовах, и его не может быть в архитектуре. В архитектуре есть набор команд, которым можно реализовать вызовы процедуры. Причем, возвращение значения в регистре EAX вообще ничем не обусловлено, с таким-же успехом его можно было-бы возвращать в EBX, участке памяти и на на стеке. С другой стороны, момент о типах вызовов и передаче аргументов вообще упущен в статье.
> Статические локальные переменные — это очень классная особенность С. В двух словах, они являются локальными переменными, которые инициализируются один раз и сохраняют свое значение между вызовами функции, в которой были объявлены.
Нет, они являются глобальными переменными, область видимости которых просто ограничена одной функцией (в отличии от локальных они не создаются при каждом входе в процедуру, и при рекурсии используется одна и та-же переменная).
> Не важно сколько раз будет вызываться наш генератор, переменная b всегда будет сохранять свое предыдущее значение. Все это потому, что она хранится вне стека и инициализируется, когда загрузчик помещает программу в память, а не по какому-то из наших машинных кодов.
Нет, она сохраняет свое значение потому, что нет инструкции, которая бы меняла данные, которые находятся по данному аддрессу (вне процедуры). Стек аддрессует точно такую же память, и к ней применимы все (почти) правила, которые и применимы к памяти, которая считается секцией данных (в семействе Windows, никогда не разбирая ядро других ОС). Впрочем, говорить об этом в статье без объяснения локальных переменных, вызовов процедур и прочего смысла нет.
И последнее:
> Также Вы можете обратить внимание, что GDB устанавливает значения для наших переменных, и так же как и во всех переменных в GDB, перед их именем стоит префикс $, в то время как префикс % используется в ассемблере от AT&T.
С какого раза можно понять смысл предложения?)