Assembler с чего начать
Перейти к содержимому

Assembler с чего начать

  • автор:

Как писать на ассемблере в 2021 году

Несмотря на наличие множества языков различной степени высокоуровневости, сегодня ассемблер не потерял своей актуальности и в индексе TIOBE находится на почётном 10-ом месте (на февраль 2021), обогнав такие модные языки как Go и Rust. Одна из причин его привлекательности – в простоте и максимальной близости к железу; с другой стороны, программирование на ассемблере всё ещё может рассматриваться как искусство и даёт совершенно особые эмоции.

Однако писать программы целиком и полностью на ассемблере — не просто долго, муторно и сложно — но ещё и несколько глупо — ведь высокоуровневые абстракции для того и были придуманы, чтобы сократить время разработки и упростить процесс программирования. Поэтому чаще всего на ассемблере пишут отдельно взятые хорошо оптимизированные функции, которые затем вызываются из языков более высокого уровня, таких как с++ и c#.

Исходя из этого, наиболее удобной средой для программирования будет Visual Studio, в состав которой уже входит MASM. Подключить его к проекту на с/c++ можно через контекстное меню проекта Build Dependencies – Build Customizations…, поставив галочку напротив masm, а сами программы на ассемблере будут располагаться в файлах с расширением .asm (в свойствах которого Item Type должно иметь значение Microsoft Macro Assembler). Это позволит не просто компилировать и вызывать программы на ассемблере без лишних телодвижений – но и осуществлять сквозную отладку, «проваливаясь» в ассемблерный исходник непосредственно из c++ или c# (в том числе и по точке останова внутри ассемблерного листинга), а также отслеживать состояния регистров наряду с обычными переменными в окне Watch.

Подсветка синтаксиса

B Visual Studio нет встроенной подсветки синтаксиса для ассемблера и прочих достижений современного IDE-строения; но её можно обеспечить с помощью сторонних расширений.

AsmHighlighter — исторически первый с минимальным функционалом и неполным набором команд — отсутсвуют не только AVX, но и некоторые из стандартных, в частности fsqrt. Именно этот факт побудил к написанию собственного расширения —

ASM Advanced Editor. В нём, помимо подсветки и сворачивания участков кода (с использованием комментариев «;[«, «;[+» и «;]») реализована привязка подсказок к регистрам, всплывающих по наведению курсора ниже по коду (также через комментарии). Выглядит это так:

;rdx=ссылка на текущий элемент входного массива
mov rcx, 8;=счётчик цикла

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

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

Asm Dude — обнаружился чуть позже. В нём автор пошёл другим путём и сфокусировал силы на встроенном справочнике команд и автодополнении, в том числе и с отслеживанием меток. Сворачивание кода там также присутствует (по «#region / #end region»), но привязки комментариев к регистрам вроде ещё нет.

32 vs. 64

С тех пор, как появилась 64-битная платформа, стало нормой писать по 2 варианта приложений. Пора завязывать с этим! Сколько можно тянуть легаси. Это же касается и расширений — найти процессор без SSE2 можно разве что в музее – к тому же, без SSE2 64-битные приложения и не заработают. Никакого удовольствия от программирования не будет, если писать по 4 варианта оптимизированных функций для каждой платформы. Только 64 бит/AVX, только хардкор! Хотя может быть и прямо противоположный взгляд — новые процессоры и так работают быстро, и оптимизацию стоит делать под старые. В общем, всё зависит от конкретной задачи.

Преимущество 64-битной платформе вовсе не в «широких» регистрах – а в том, что этих самых регистров стало в 2 раза больше – по 16 штук как общего назначения, так и XMM/YMM. Это не только упрощает программирование, но и позволяет значительно сократить обращения к памяти.

FPU

Если ранее без FPU было никуда, т.к. функции с вещественными числами оставляли результат на вершине стека, то на 64-битной платформе обмен проходит уже без его участия с использованием регистров xmm расширения SSE2. Intel в своих руководствах также активно рекомендует отказаться от FPU в пользу SSE2. Однако есть нюанс: FPU позволяет производить вычисления с 80-битной точностью — что в некоторых случаях может оказаться критически важным. Поэтому поддержка FPU никуда не делаcь, и рассматривать её как устаревшую технологию совершенно точно не стоит. Например, вычисление гипотенузы можно делать «в лоб» без опасения переполнения,

а именно

fld x fmul st(0), st(0) fld y fmul st(0), st(0) faddp st(1), st(0) fsqrt fstp hypot

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

Пример оптимизации: преобразование Хартли

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

Итак, в качестве задачи возьмём алгоритм (медленного) преобразования Хартли:

static void ht_csharp(double[] data, double[] result) < int n = data.Length; double phi = 2.0 * Math.PI / n; for (int i = 0; i < n; ++i) < double sum = 0.0; for (int j = 0; j < n; ++j) < double w = phi * i * j; sum += data[j] * (Math.Cos(w) + Math.Sin(w)); >result[i] = sum / Math.Sqrt(n); > >

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

код (комментарии удалены)

ht_asm PROC local sqrtn:REAL10 local _2pin:REAL10 local k:DWORD local n:DWORD and r8, 0ffffffffh mov n, r8d mov r11, rcx xor rcx, rcx mov r9, r8 dec r9 shr r9, 1 mov r10, r8 sub r10, 2 shl r10, 3 finit fld _2pi fild n fdivp st(1), st fstp _2pin fld1 fild n fsqrt fdivp st(1), st ; mov rax, r11 mov rcx, r8 fldz @loop0: fadd QWORD PTR [rax] add rax, 8 loop @loop0 fmul st, st(1) fstp QWORD PTR [rdx] fstp sqrtn add rdx, 8 mov k, 1 @loop1: mov rax, r11 fld QWORD PTR [rax] fld st(0) add rax, 8 fld _2pin fild k fmulp st(1),st fsincos fld1;=u fldz;=v mov rcx, r8 dec rcx @loop2: fld st(1) fmul st(0),st(4) fld st(1) fmul st,st(4) faddp st(1),st fxch st(1) fmul st, st(4) fxch st(2) fmul st,st(3) fsubrp st(2),st fld st(0) fadd st, st(2) fmul QWORD PTR [rax] faddp st(5), st fld st(0) fsubr st, st(2) fmul QWORD PTR [rax] faddp st(6), st add rax, 8 loop @loop2 fcompp fcompp fld sqrtn fmul st(1), st fxch st(1) fstp QWORD PTR [rdx] fmulp st(1), st fstp QWORD PTR [rdx+r10] add rdx,8 sub r10, 16 inc k dec r9 jnz @loop1 test r10, r10 jnz @exit mov rax, r11 fldz mov rcx, r8 shr rcx, 1 @loop3:;[ fadd QWORD PTR [rax] fsub QWORD PTR [rax+8] add rax, 16 loop @loop3;] fld sqrtn fmulp st(1), st fstp QWORD PTR [rdx] @exit: ret ht_asm ENDP

Обратите внимание: тут нет ни разворачивания цикла, ни SSE/AVX, ни косинусных таблиц, ни снижения сложности за счёт «быстрого» алгоритма преобразования. Единственная явная оптимизация — это итеративное вычисление синуса/косинуса во внутреннем цикле алгоритма непосредственно в регистрах FPU.

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

Результаты авто-оптимизации программы на c++ также могут сильно зависеть от настроек параметров компилятора и выбора допустимого расширенного набора инструкций (SSE/AVX/etc). При этом есть два нюанса:

  1. Современные компиляторы склонны всё возможное вычислять на этапе компиляции – поэтому вполне возможно в откомпилированном коде вместо алгоритма увидеть заранее посчитанное значение, что при замере производительности даст преимущество компилятору в 100500 раз. Во избежание этого в моих замерах используется внешняя функция zero(), добавляющая неопределённости входным параметрам.
  2. Если компилятору указать «не использовать AVX» — это ещё не значит, что в полученном коде будет отсутствовать AVX. Внешние библиотеки сами проверяют доступный набор команд на текущей платформе и выбирают соответствующую реализацию. Поэтому единственно надёжный способ сравнения производительности в таком случае – испытывать код на платформе, где AVX отсутствует в принципе.

Итак, компилятор Visual Studio 2019, целевая платформа AVX2, Floating Point Model=Precise. Чтобы было ещё интереснее — будет измерять из проекта на c# на массиве из 10000 элементов:

C# ожидаемо оказался медленнее с++, а функция на ассемблере оказалась быстрее в 9 раз! Однако ещё рано радоваться — установим Floating Point Model=Fast:

Как видно, это помогло значительно ускорить код и отставание от ручной оптимизации составило всего лишь в 1.8 раз. Но вот что не изменилось – так это погрешность. Что тот, что другой вариант дал ошибку в 4 значащих цифры – а это немаловажно при математических вычислениях.

В данном случае наш вариант оказался и быстрее, и точнее. Но так бывает не всегда – и выбирая FPU для хранения результатов мы неизбежно будем терять в возможности оптимизации векторизацией. Также никто не запрещает комбинировать FPU и SSE2 в тех случаях, когда это имеет смысл (в частности, такой подход я использовал в реализации double-double арифметики, получив 10-кратное ускорение при умножении).

Дальнейшая оптимизация преобразования Хартли лежит уже в другой плоскости и (для произвольного размера) требует алгоритма Блюстейна, который также критичен к точности промежуточных вычислений. Ну а этот проект можно скачать на GitHub, и в качестве бонуса там также можно найти реализацию функций для суммирования/масштабирования массивов на FPU/SSE2/AVX.

Что почитать

Литературы по ассемблеру навалом. Но можно выделить несколько ключевых источников:
1. Официальная документация от Intel. Ничего лишнего, вероятность опечаток минимальна (кои в печатной литературе встречаются повсеместно).
2. Официальная документация от Microsoft.
3. Онлайн справочник, спарсенный из официальной документации.
4. Сайт Агнера Фога, признанного эксперта по оптимизации. Также содержит образцы оптимизированного кода на C++ с использованием интринсиков.
5. SIMPLY FPU.
6. 40 Basic Practices in Assembly Language Programming.
7. Все, что нужно знать, чтобы начать программировать для 64-разрядных версий Windows.

Appendix: Почему бы просто не использовать интринсики (Intrinsics)?

Скрытый текст

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

  • Не вся оптимизация делается векторизацией. Если во времена DOS оптимизация делалась за счёт экономии тактов и количества обращений к памяти, то сейчас основной инструмент оптимизации – это организация оптимальной работы с памятью во избежание промахов кеша.
  • Интринсики к новым инструкциям появляются с некоторым запаздыванием. Недостающие интринсики нельзя добавить простым включением заголовочного файла – их поддержка должна быть реализована на уровне компилятора.
  • Не на все инструкции возможно сделать интринсики. Когда оптимизация касается точности математических выражений, можно добиться значительных улучшений, программируя непосредственно на математическом сопроцессоре (FPU). Для команд сопроцессора же интринсики отсутствуют. Они также отсутствуют для команд, на результат которых влияют флаги переноса/переполнения/etc.
  • Интринсики не представляют из себя какой-либо высокоуровневый фреймворк – по факту, это не более чем лишь ещё один уровень мнемоник над ассемблерными инструкциями, мало чем отличающийся от ассемблерных вставок. Что автоматически означает, что код вовсе не становится более читаемым, а при его написании так или иначе нужно придерживаться ассемблерного стиля мышления.
  • Также, из C++ кода вовсе не очевидно, что существуют какие-то ограничения на количество одновременно используемых SIMD-регистров. В 32-х битном ассемблере вы не можете использовать XMM8 наравне с XMM0 / XMM7 – код просто не откомпилируется. А интринсиками вы можете определить хоть тысячу одновременно используемых регистров — и компилятор вынужден будет сам решать, что хранить в регистрах, что в памяти, и как между собой их оптимально комбинировать. В таком случае применение интринсиков не даёт никаких преимуществ в плане увеличения производительности – компилятор работает с ними так же, как и с обычными структурами на C++.
  • Программировать на ассемблере не так уж и сложно, особенно если не пытаться делать на нём хитрые высокоуровневые конструкции. Многое можно почерпнуть, изучая ассемблерный листинг простых алгоритмов в режиме отладки и с различными уровнями оптимизации – компилятор от Microsoft производит достаточно лёгкий для понимания и в то же время эффективный код, комментируя его исходным кодом на C++.
  • Программирование
  • Assembler

Изучение ассемблера: суть и с чего начать?

Начну немного с предистории. Живу под «гордым» названием веб-разработчик. Для клиентов маг и бездарь одновременно (хотя, второе чаще). Для понимающих просто очередной фронтендщик, который пишет велосипеды на ванильке. Помимо JS знаю, наверное, ниже среднего PHP, BASH и Lua. Когда-то учил Basic, Pascal, C и Python. И тут понятно, что не могу я назвать себя программистом — левел не тот. Вот по этой причине и для души хочу начать изучать ассемблер.

А теперь к сути. Почитал немного информации, понял, что есть команды процессора, используя которые мы создаем программу. Эти команды у разных процессоров/архитектур разные. Но как с этим всем работать пока не понял. Исходя из этого у меня есть ряд вопросов:

  1. Я так понимаю, что текст программы на ассемблере необходимо компилировать, да? Есть какой-нить предустановленный компилятор в GNU/Linux?
  2. Есть какие-то общие правила написания программ? Что-то вроде var arr; function()<>;. Как-то же необходимо связывать меж собой команды процессора. Что это за WASM или TASM?
  3. Сборка программы на ассемблере возможна не на устройстве, для которого пишется программа? Если сравнивать с компиляцией ядра Linux.
  4. Я так понимаю, что для «переменных» необходимо жестко указывать ячейку памяти процессора и ОЗУ, да? Что на счет этого стоит учить? Необходимо для старта читать кучу материала о страницах памяти и т.д.?

Планирую начать с чего-то простого, например, Z80 или MC6800. Думаю, завтра у меня еще вопросы будут 🙂 .

В общем, кто что посоветует, с чего начать, где эти основы брать? А то я как по среди моря не вижу куда плыть.

P.S. За ранее всем спасибо!

EmgrtE ★★★★
27.12.15 03:02:43 MSK
1 2 3 4 →

рано тебе в эту степь

anonymous
( 27.12.15 03:14:38 MSK )
anonymous
( 27.12.15 03:24:31 MSK )

  • Скачай интеловские мануалы (Intel® 64 and IA-32 Architectures Software Developer’s Manuals) одним файлом и в любой непонятной ситуации читай их.
  • Пиши под своё железо и свою ОС, не городи лишних виртуалок и слоёв абстракции.
  • Выбери инструменты, которые развиваются и поддерживаются (например, fasm).
  • Начни с чтения хэлловорда с документацией к ассемблеру и интеловскими мануалами наперевес.
  • Измени код хэлловорда до, например, калькулятора.
  • Выложи код и попроси опытных людей сделать ревью.
  • Читай чужой код.

Компилировать (ассемблировать) нужно, ассемблером. Masm, nasm, fasm, tasm и прочие — это ассемблеры. Отличаются, в основном, синтаксисом, т.к. язык ассемблера по сути только представляет кишки процессора в человекочитаемом виде. А раз архитектура одна, то и яйца те же, только в профиль.

Правила написания есть, довольно примитивные. Типа «одна строчка — одна команда». Научишься по примерам и документации.

Собирать код можно где угодно, где запускается твой ассемблер.

Да, руками перекладываешь байты между регистрами и памятью. Начни с хэловорда, гугли непонятное. Много знать полезно, но всё со временем, можно и с малого начать.

Общий совет — бери и делай. Вместо вопросов «как делать» лучше спрашивать «почему не работает» или «как оно работает» с конкретным кодом.

d ★★★★
( 27.12.15 03:26:13 MSK )

возьми книгу «Структуры данных и алгоритмы» Рацеев, там много хелоувордов. Почитай книгу Программирование на языке ассемблера Nasm для ОС UNIX. там очень хорошо все разжеванно. Но самое главное, как писали выше это просто писать код

SmilePlz ★
( 27.12.15 03:55:40 MSK )
Ответ на: комментарий от d 27.12.15 03:26:13 MSK

Пиши под своё железо и свою ОС, не городи лишних виртуалок и слоёв абстракции

Все бы хорошо, но асм под чужой протмодой это самое унылое, что только можно придумать. Ничто не сравнится с прямой записью в видеобуфер и ловлей девятого инта для тср. Уже не говоря об ощущении той мощи, которую тебе дают univbe и dos4gw/pharlap. Колить write и brk можно и под сишкой, ничего особо интересного в этом нет.

arturpub ★★
( 27.12.15 03:55:50 MSK )
Последнее исправление: arturpub 27.12.15 03:56:32 MSK (всего исправлений: 1)

anTaRes ★★★★
( 27.12.15 04:02:11 MSK )

как с этим всем работать пока не понял

Кроме самой программы есть еще вопрос, как обьяснить загрузчику, куда какие части класть в рантайме (потому что перед запуском процесс конструируется из секций исполняемого файла). В досе самые примитивные — .com программы, это тупо образ рантайма

Ты пишешь программу в секции code, размещаешь статические данные в data и bss, иногда указываешь размер стека, а ассемблер (tasm, masm, gas) это все собирает либо в объектные файлы, которые можно линковать линкером (tlink, link, ld), либо сразу в исполняемые (фасм на винде, например). Динамическая память выделяется как обычно malloc (или int21/48), к секциям и асму в целом отношения не имеет.

arturpub ★★
( 27.12.15 04:13:04 MSK )
Ответ на: комментарий от anonymous 27.12.15 03:14:38 MSK

напротив, очень поздно. Я лет в 12 понял суть работы ЦП.

targitaj ★★★★★
( 27.12.15 04:26:31 MSK )

Одна звезда, а lorcode так и не осилил — рано тебе ещё в assembler.

beastie ★★★★★
( 27.12.15 04:26:43 MSK )
Ответ на: комментарий от arturpub 27.12.15 04:13:04 MSK

Ты пишешь программу в секции code,

Исполняемое — в секции .text

anonymous
( 27.12.15 04:27:32 MSK )
Ответ на: комментарий от anonymous 27.12.15 04:27:32 MSK

Где как, у тасма вроде code называлась.

arturpub ★★
( 27.12.15 04:28:52 MSK )
Ответ на: комментарий от arturpub 27.12.15 04:28:52 MSK
anonymous
( 27.12.15 04:31:42 MSK )
Ответ на: комментарий от targitaj 27.12.15 04:26:31 MSK

Конечно, с этого начинать надо, чтобы потом не плакать в бложиках pointers considered harmful. Если не осилил такую примитивную вещь, как асм, то в низкий уровень вход заказан.

arturpub ★★
( 27.12.15 04:32:50 MSK )
Ответ на: комментарий от arturpub 27.12.15 04:28:52 MSK

А какой синтаксис в конкретном ассемблере — дело десятое, а секции и в африке секции

anonymous
( 27.12.15 04:33:03 MSK )

Следовало бы начать с языка Си.

Deleted
( 27.12.15 04:34:14 MSK )
Ответ на: комментарий от anonymous 27.12.15 04:31:42 MSK

Анон, ну что ты мне свой эльф суешь? Кроме линукса и другие системы есть.

arturpub ★★
( 27.12.15 04:35:05 MSK )
Ответ на: комментарий от arturpub 27.12.15 04:35:05 MSK

Дурак что ли? Твои bss с data — это не elf по-твоему. К тому же elf везде почти

anonymous
( 27.12.15 04:43:49 MSK )
Ответ на: комментарий от arturpub 27.12.15 04:32:50 MSK

Угу, «начинать». Только двое из трёх программеров нашего подрядчика имеют представление о работе машины на уровне двоичного когда. Они пишут на жабе. Из приходивших на собеседования на позицию программера молодых мальчиков — никто вообще. Я не могу этого понять. Как можно писать код, если ты не понимаешь что именно делает машина? Может быть я ошибаюсь и, наоборот, лучше не знать? Может быть знание низкого уровня отвлекает? Сам я не зарабатываю программированием.

Задавали соискателям задачку. Есть 4 млрд + 1 число, из которых 4 млрд — парные и 1 непарное. Надо найти это самое единственное непарное число. Решается на низком уровне просто элементарно, если знаешь как работает машина. Было интересно послушать какие конструкции лепили соискатели. Ппц, чего они лепили. Сортировки, хеши, таблицы. Мрак.

targitaj ★★★★★
( 27.12.15 04:44:54 MSK )
Ответ на: комментарий от targitaj 27.12.15 04:44:54 MSK
arturpub ★★
( 27.12.15 04:47:26 MSK )
Ответ на: комментарий от targitaj 27.12.15 04:44:54 MSK

Решается на низком уровне просто элементарно, если знаешь как работает машина.

anonymous
( 27.12.15 04:53:24 MSK )
Ответ на: комментарий от anonymous 27.12.15 04:53:24 MSK

targitaj ★★★★★
( 27.12.15 04:56:16 MSK )
Ответ на: комментарий от anonymous 27.12.15 04:53:24 MSK

Совсем стыд потеряли.

arturpub ★★
( 27.12.15 04:57:41 MSK )
Ответ на: комментарий от arturpub 27.12.15 04:57:41 MSK

Тише, молодой челове, у меня бессоница, мне всё можно

anonymous
( 27.12.15 05:03:04 MSK )
Ответ на: комментарий от arturpub 27.12.15 04:13:04 MSK

В досе самые примитивные — .com программы, это тупо образ рантайма

Это да, при загрузке твой файлик помещается в один сегмент по адресу 100h, перед ним какой-то мусор, не помню уже, что, видимо параметры запуска и окружение. Все сегментные регистры ставятся на твой сегмент.

Динамическая память выделяется как обычно malloc (или int21/48), к секциям и асму в целом отношения не имеет.

Как сделать в асме под GNU/Linux это я не очень понял.

Xenius ★★★★★
( 27.12.15 05:09:10 MSK )

Я вообще начинал с Программирование однокристальных микропроцессоров. В бумаге. (Аппаратную часть тех времен, можно не зацикливаться). Потом на TurboC-ях хелловорды писались, и компилировались с дебагинфо, потом дебажились TASM-овоским дебагером. Помаленьку хелловорды начали линковаться с модулями написанные на асме(реализовывались примитивные функции). Потом внезапно открыл для себя Flat Assembler, который упростил прототипирование.
В любом случае, нужно писать и писать и писать. Я бы посоветовал по такой схеме вкуривать:
1. Знакомимся с базовыми понятиями: регистры, память, стек и данные в нем, и что с ними можно делать(основные команды как для вхождения нужно знать я бы сказал не более 30%);
2. Знакомимся с потоком выполнения: последовательность исполнения команд, как работают (без)условные переходы, вызовы процедур, возврат из них, аналоги высокоровневых операторов управления(if,while);
3. Берем(ставим себе) задачку, и решаем её на бумаге. Как в школе учили/учат: блоксхема, разбиваем на процедуры, подбираем тестовые данные. Знаете другой язык — отлаживаете алгоритмы на нем абы потом не гадать: алгоритм не корректный или реализация кривая.
4. Реализуем процедуры, обязательно наступая не все грабли(ну очень советую тот же Flat).
5. Пункт 3 и 4 повторяем до опупения.
На самом деле, кодинг на ассемблере принципиально ничем не отличается от чего либо другого. Количество деталей, уровень абстракции. Вывих мозга начинается там где нужна глубокая оптимизация всего и вся. В 95% случаев таковая не нужна, хватает того что может предоставить оптимизатор С/С++.

Да кстати, у вас есть возможность войти в это ещё плавнее. Говорите есть опыт с Lua. Как ни странно, но понятие ассемблера тоже входит и мнемокод для виртуальных процессоров, виртуальных машин. Lua, Java, .NET, Python, PHP. За 3 первых точно скажу, что написав хелловорлд на высокоуровневом языке можно посмотреть комманды виртуальной машины соотвествующие этому коду. И даже тот же С/С++ можно просить родить ассемблер код. Не советую смотреть что-либо программок больше 3-5 процедур. А крутя ручки оптимизации.

FeyFre ★★★★
( 27.12.15 05:09:51 MSK )
Ответ на: комментарий от anonymous 27.12.15 05:03:04 MSK
arturpub ★★
( 27.12.15 05:12:24 MSK )

Я думаю, можешь доками Intel не заморачиваться.

Просто берёшь fasm, качаешь, там будет и сам ассемблер и примеры и дока по командам процессора.

В принципе особой разницей между nasm и fasm нету, но fasm позволяет глубже погрузиться в низкоуровневую фигню, а nasm (и GAS, gnu assembler) зато удобнее когда нужно включить ассемблерный код в большой проект.

Кроме того, fasm написан сам на себе, а nasm на C, что опять же делает nasm удобнее для real world-задач, когда ты можешь собирать код для x86 на высокопроизводительной машине с каким-нибудь ультраспарком или PowerPC, а fasm работает только на x86-компьютерах, хотя может ассемблировать для любой ОС с любой другой (например можно собирать виндовые exe под линуксом и наоборот).

Xenius ★★★★★
( 27.12.15 05:15:10 MSK )
Последнее исправление: Xenius 27.12.15 05:15:41 MSK (всего исправлений: 1)

Ответ на: комментарий от Xenius 27.12.15 05:09:10 MSK

Это да, при загрузке твой файлик помещается в один сегмент по адресу 100h, перед ним какой-то мусор, не помню уже, что, видимо параметры запуска и окружение. Все сегментные регистры ставятся на твой сегмент.

PSP — Program segment prefix. Как же меня коробит сокращение PlaySatiton Portable к PSP.

FeyFre ★★★★
( 27.12.15 05:15:31 MSK )
Ответ на: комментарий от Xenius 27.12.15 05:09:10 MSK

Как сделать в асме под GNU/Linux это я не очень понял.

Что именно, память выделить? Если libc в процессе и через main() работаем, то malloc, иначе сисколить, выяснив номер brk (это лишь теория, афаик не иметь libc в юникслайках это дебильная затея).

Там помойму дос FCB размещал, пока не стало deprecated.

arturpub ★★
( 27.12.15 05:16:03 MSK )
Последнее исправление: arturpub 27.12.15 05:17:07 MSK (всего исправлений: 1)

В общем, не с того конца ты подходишь. Не с языка начинать надо. Нужно понять что делает ЦП. Суть. А суть простая — копирование чисел и преобразование чисел. До меня дошло всё это в тот самый момент, когда я понял что точки на экране — это попросту единицы в ОЗУ. 1 — есть точка. 0 — нет точки. Или, точнее, 1 — точка горит, 0 — погашена. А изменение картинки на экране достигается тупо мат. преобразованиями и копированием. Это было потрясающе. Тогда у меня был Вектор 06Ц, я писал на бейсике и изучал синенькую брошюрку «От бейсика к ассемблеру». Я долго не мог понять, какого хрена считай что все команды ЦП сводились к копированию.

Короче, без понимания и хорошего знания математики на низком уровне делать нечего.

Как начать изучение Assembler’a?

С чего начать изучение ассемблера
Хочу научиться программировать на ассемблере, но не знаю с чего начать, какой компилятор скачать, в.

Вставка функции Assemblera в Virtual Pascal
1. Написать программу в среде Virtual Pascal (на Паскале), использующую представленную функцию. .

С чего начать изучение асма?
и так, я бы хотел заняться с ассемблером серьезно ((: вот с чего бы начать? я слышал что надо.

С чего начать изучение ассемблера?
Хочу начать программировать на assembler, скажите пожалуйста с чего начать? какую программу лучше.

Регистрация: 10.01.2016
Сообщений: 22
Assembler & Win32. Курс молодого бойца
http://www.codenet.ru/progr/asm/newbee/
1830 / 926 / 167
Регистрация: 23.07.2018
Сообщений: 3,127
Записей в блоге: 3

Лучший ответ

Сообщение было отмечено CyberMyzhik как решение

Решение

Так же, как изучение любого Отладчика, Загрузчика, Компоновщика, Компилятора:
на практике с использованием справочных руководств для того Ассемблера, который нужно изучить.
https://sourceware.org/binutil. index.html
https://www.nasm.us/xdoc/2.15.05/nasmdoc.pdf
https://flatassembler.net/docs.php?article=manual
https://www.ibm.com/support/kn. mp1023.pdf
В зависимости от целей и условий изучения, возможно, ещё придётся почитать или написать какие-нибудь учебники,
а также познакомиться с исходным кодом изучаемого Ассемблера.
https://sourceware.org/git/?p=. ads/master

Ушел с форума

Автор FAQ

16186 / 7520 / 1041
Регистрация: 11.11.2010
Сообщений: 13,524

CyberMyzhik,
так же как любой язык, при помощи учебников и бесконечной практики. И быть готовому к тому, что результат появится где-то через полгода-год. А если нужны быстрые результаты, то ассемблер не для тебя

Прощай, Мир!
1672 / 830 / 253
Регистрация: 26.05.2012
Сообщений: 3,056

ЦитатаСообщение от Mikl___ Посмотреть сообщение

результат появится где-то через полгода-год.
а как этот результат будет выглядеть в денежном эквиваленте.
Регистрация: 23.06.2020
Сообщений: 166
Mikl__, А какие именно учебники?

Эксперт по электронике

8359 / 4249 / 1610
Регистрация: 01.02.2015
Сообщений: 13,211
Записей в блоге: 5

CyberMyzhik, так вы ещё не успели приступить?

Скажите, а дорого стоит получить зачёт по language incognita?
Видимо, не очень, но хотелось бы конкретики.

3406 / 1825 / 489
Регистрация: 28.02.2015
Сообщений: 3,697

ЦитатаСообщение от CyberMyzhik Посмотреть сообщение

А какие именно учебники?

Любые которые Вам подойдут. Полезные ссылки, книги, инструменты или Электронный учебник.
Хотите быстрый результат Вам нужно искать «своего автора», который пишет на понятном Вам языке.

Эксперт по электронике

8359 / 4249 / 1610
Регистрация: 01.02.2015
Сообщений: 13,211
Записей в блоге: 5

Не будет там никакого результата — это некротема конца августа.
Похоже, студент закрывал весеннюю сессию.

Прошло 3 месяца — обучение на том же месте.

Значит сдача сессии не запредельно дорогая, а при высокой массовости явки, ещё и подарочные скидки.

1830 / 926 / 167
Регистрация: 23.07.2018
Сообщений: 3,127
Записей в блоге: 3

ЦитатаСообщение от CyberMyzhik Посмотреть сообщение

А какие именно учебники?
А какой именно Assembler?
И какова цель и, хотя бы приблизительные, сроки изучения?
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
Помогаю со студенческими работами здесь

С чего начать углубленное изучение ассемблера
Я прочитал несколько книг по ассемблеру, статей, написал несколько программ, умею пользоваться.

Стоит ли отрываться/бросать изучение С++, чтобы начать учить FASM
Тема изъезженная, но ситуации бывают разные. Не сочтите за глупость, но слишком стал беспокоить.

Что посоветуете тому, кто хочет начать учить Java? С чего начать изучение?
Какие книги посоветуете по Java? Какие программы? Дело в том, что хочу начать учить разработку.

Как начать изучение сетей?
Я всерьез решил изучить досконально сети, на данный момент мои познания довольно скудны и не.

Как лучше начать изучение системы?
а подскажите, пожалуйста, я вот совсем в Ubuntu новичок и собираюсь начать изучение с нуля с.

Как начать изучение разработки под ios?
Добрый день, господа-программисты. Я задумался над тем, чтобы начать изучать как разрабатывать.

С чего начать изучать ассемблер в 2021?

Хочу научится писать максимально оптимизированный код, чтобы понимать как работают все конструкции языка на низком уровне. Нашел книгу Калашников О. – Ассемблер – это просто. Учимся программировать, 2011 г. Что-то более новое что советовали бы на форумах не нашел. В этой книге рассматриваются 16 и 32 разрядные системы, и даже файлы примеров запустить не получается. Хотелось бы какую-то книгу современную книгу по ассемблеру для 64 битных систем. Какую версию ассемблера лучше выбрать для начала?

  • Вопрос задан более двух лет назад
  • 2246 просмотров

1 комментарий

Простой 1 комментарий

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *