Как писать на ассемблере на mac os

Обновлено: 06.07.2024

Эта статья предназначена для тех, кто только начинает изучать язык ассемблера. Довольно часто можно встретить книги и статьи с заголовками вроде «Ассемблер это просто». Подобные слоганы — не более чем маркетинговый ход — нужно как-то привлекать клиентов (читателей). Конечно, научиться писать простые программы очень легко. Но все зависит от задач, которые вы перед собой ставите. Научиться водить машину легко. Однако бывает только один водитель-ас.

Подготовка к работе

Думаю, вы уже знакомы с программированием — вы знаете любой из языков высокого уровня (C, PHP, Java, JavaScript и т. д), Вы работали с шестнадцатеричными числами, плюс вы знаете, как использовать командную строку в Windows , Linux или macOS.

На каком процессоре лучше всего учить язык если набор инструкций у всех разный?

Знаете ли вы что такое 8088? Это дедушка всех компьютерных процессоров! И живой дедушка. Я бы сказал — бессмертный и постоянный. Если из вашего процессора, будь то Ryzen, Core i9 или какого-то другого типа, вырвите все застрявшие там гаджеты под влиянием технического прогресса, то старый добрый 8088 останется.

SGX, ММХ, 512-битные регистры SIMD и другие нововведения приходят и уходят.Но дедушка 8088 остался без изменений. Сначала подружитесь с ним. Тогда вы легко справитесь с любыми гаджетами вашего процессора.

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

Какие процессы происходят в процессоре после того, как ты запускаешь программу.

После запуска программного обеспечения и загрузки его операционной системой в ОЗУ процессор обращается к первому байту программы. Выцепляет инструкцию оттуда и выполняет ее, а после ее выполнения переходит к следующей. И так до конца программы.

Некоторые инструкции имеют объем в один байт, а некоторые – в два, три или больше. Это выглядит как то так:

Вернее, даже так:

И только машина способна понять такое. Так что еще несколько лет назад разработчики придумали более гуманный способ общения с компьютером : они создали ассемблер.

С помощью ассемблера можно теперь не танцевать с бубном вокруг шестнадцатерных чисел, а и писать инструкции в мнемонике:

Но ведь и читать-то это намного проще! С другой стороны, если ты увидел ассемблерный код впервые и не знаешь, как его интерпретировать, то такая мнемоника для тебя, скорей всего, тоже будет не ясна.

Зачем нужны регистры процессора и как ими пользоваться.

Какие функции выполняет инструкция Mov ? Присваивает число, которое указано справа, переменной, которая указана слева.

Регистр процессора или ячейка ОЗУ – это одна из переменных в памяти компьютера. Процессор быстрее работает с регистрами, чем с памятью, потому что регистры находятся внутри него. Но у процессора мало регистров, поэтому в любом случае что-то нужно хранить в памяти.

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

У процессора 8088 регистры 16-битные, их восемь штук (в скобках указаны типичные способы применения регистра):

  • AX — общего назначения (аккумулятор);
  • BX — общего назначения (адрес);
  • CX — общего назначения (счетчик);
  • DX — общего назначения (расширяет AX до 32 бит);
  • SI — общего назначения (адрес источника);
  • DI — общего назначения (адрес приемника);
  • BP — указатель базы (обычно адресует переменные, хранимые на стеке);
  • SP — указатель стека.

Хотя каждый регистр имеет типичный вариант использования, вы можете использовать их как хотите. Первые четыре регистра — AX, BX, CX и DX — при желании можно использовать не полностью, а половинками по 8 бит (старший H и младший L): AH, BH, CH, DH и AL, BL, CL, DL. Например, если вы напишете в AX число 0x77AA (mov ax, 0x77AA), то 0x77 попадет в AH, а 0xAA — в AL.

Теория пока закончена. Сейчас мы с тобой подготовим рабочее место и напишем программу «Hello World!» для того, чтобы понять, как эта теория работает на практике.

Подготовка рабочего места

Тебе надо как-то редактировать исходный код. Ты можешь пользоваться любым текстовым редактором, который тебе по душе: Emacs, Vim, Notepad, Notepad++ — сойдет любой. Лично мне нравится редактор, встроенный в Far Manager, с плагином Colorer.

Чтобы в современных ОС запускать программы, написанные для 8088, и проверять, как они работают, тебе понадобится DOSBox или VirtualBox.

Пишем, компилируем и запускаем программу «Hello, world!»

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

Ассемблер для начинающих

Если вы не понимаете, что здесь написано, не волнуйтесь. А пока попробуйте к ассемблерному коду привыкнуть, пощупайте пальцами. Я все объясню ниже. Кроме того, студенческая мудрость гласит: «Ты что-нибудь понимаешь? Перечитал и переписал несколько раз. Сначала непонятное станет знакомым, а потом знакомое станет понятным. «

Для запуска командной строки, в Windows есть cmd.exe. Теперь нужно зайти в папку nasm и скомпилировать программу, используя вот такую команду:

Чтобы запустить этот файл в современной ОС, открой DOSBox и введи туда вот такие три команды:

Ассемблер для начинающих

Инструкции и директивы

В нашей программе есть только три вещи: инструкции, директивы и метки.

Инструкции. Вы уже знакомы с инструкциями (мы рассмотрели их немного раньше) и знаете, что это мнемоника, которую компилятор переводит в машинный код.

Директивы (у нас их две: org и db )- это команды, которые вы даете компилятору. Взятые по отдельности, каждая директива сообщает компилятору, что на этапе сборки необходимо то-то и то-то действие. Директива не переводится в машинный код, но влияет на то, как генерируется машинный код.

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

Директива db указывает компилятору вставить байтовую строку в ваш код. Здесь мы указываем через запятую, что туда помещать. Это может быть строка (в кавычках), символ (в одинарных кавычках) или просто число.

В нашем случае: db "Hello, world", '!', 0 .

Убедитесь, что я вырезал восклицательный знак на остальной части строки, чтобы показать, что вы можете работать с отдельными символами в директиве db. В общем, лучше писать так:

Условные, безусловные переходы и метки

Метки используются для двух целей: для задания имен переменных, которые хранятся в памяти (в нашей программе есть только одна такая метка: string), и для обозначения участков кода, в которых вы переходите из других мест в программе ( В нашем ассортименте три таких лейбла — те, которые начинаются с двух символов-собак).

Что значит «прыгать с других мест в программе»? Процессор обычно выполняет инструкции последовательно, одну за другой. Но если вы хотите организовать ветвление (условие или цикл), вы можете использовать инструкцию ветвления. Вы можете перейти вперед от текущей инструкции или назад.

У тебя в распоряжении есть одна инструкция безусловного перехода ( jmp ) и штук двадцать инструкций условного перехода.

Мы используем две инструкции перехода: je и jmp . Первый выполняет условный переход (Jump if equal — прыгать, если равен), второй (Jump) — безусловный. С их помощью мы организовали цикл.

Обратите внимание, что метки начинаются с буквы, подчеркивания или собаки. Вы также можете вставлять числа, но не в начале. В конце метки необходимо поставить двоеточие.

Выбор регистров, алгоритм и комментарии

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

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

Ассемблер для начинающих

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

  1. Поместить в BX адрес строки.
  2. Поместить в AL очередную букву из строки.
  3. Если вместо буквы там 0, выходим из программы — переходим на 6-й шаг.
  4. Выводим букву на экран.
  5. Повторяем со второго шага.
  6. Конец.

Мы не можем использовать AX для хранения адресной информации, так как нет таких инструкций, которые бы использовали его в качестве регистра-источника.

Данные с клавиатуры

Если программа не может взаимодействовать с пользователем и выполнять его команды, то она бесполезна. Смотри, как можно считывать данные с помощью клавиатуры.Сохрани вот этот код как second.asm.


Потом иди в командную строку и скомпилируй его в NASM:

Затем запусти скомпилированную программу в DOSBox:

Как работает программа? Две строки после метки @@ start вызывают функцию BIOS, которая считывает символы с клавиатуры. Он ожидает, пока пользователь нажмет клавишу, а затем помещает ASCII-код полученного значения в регистр AL. Например, если вы нажмете заглавную A, 0x41 попадет в AL, а если вы нажмете заглавную a, 0x61.

Затем смотрим: если нажата клавиша с кодом 0x1B (клавиша ESC), мы выходим из программы. Если клавиша ESC не нажата, мы вызываем ту же функцию, что и в предыдущей программе, чтобы показать символ на экране. После показа — перейти в начало (jmp): start.

На заметку, инструкция cmp (от слова Compare — сравнивать ) выполняет сравнение, инструкция je(Jump if Equal) – прыжок в конец программы.

Автоматизируем компиляцию и смотрим машинный код

Если тебе интересно, в какой машинный код преобразуются инструкции программы, скомпилируй исходник вот таким вот образом (добавь опцию -l ):

Тогда NASM создаст не только исполняемый файл, но еще и листинг: second.lst . Листинг будет выглядеть как-то так.


Вы, наверное, уже устали вводить длинную последовательность одних и тех же букв в командную строку каждый раз при компиляции. Если вы используете Windows, вы можете создать командный файл (например, m.bat) и вставить в него следующий текст.


Теперь ты можешь компилировать свою программу вот так:

Само собой, вместо first ты можешь подставить любое имя файла.

Выводы

В общем теперь ты знаешь как написать простейшю программе на ассемблере как ее скомпилировать и какие средства для этого нужны. Однако, если ты прочтешь одну статью, то вряд ли станешь настоящим программистом на ассемблере.Чтобы создать и написать на нем что-то действительно стоящее – например, Floppy Bird и “МикроБ”, тебе еще придется немало потрудиться. Но это уже твой первый шаг в этом направлении.

Лучший способ сделать это - использовать класс WordPress для аутентификации пользователей. Вот мои решения:

1. Включите следующий PHP-файл WordPress:

2. Создайте объект класса PasswordHash :

$wp_hasher = new PasswordHash(8, true);

3. вызов функции CheckPassword для аутентификации пользователя:

$check = $wp_hasher->CheckPassword($password, $row['user_pass']);

4. проверьте переменную $check :

Если Вы используете PowerPC Mac, изучаете встроенный ассемблер gcc. Иначе изучите nasm. Я не могу дать достойные ссылки на PPC ASM (они немногочисленны), но я предлагаю следующие вещи изучить x86 asm:

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

Редактирование: Кроме того, получите gcc и такой от XCode не Macports или somesuch. Вы находитесь в для мира уродливых Мужественных файлов, если Вы не делаете. Не забава диагностировать проблемы формата файла, когда Вы только запускаете взламывание asm.

Чтобы начать изучать блок, Вы могли бы хотеть запуститься с простых программ C и попросить, чтобы GCC генерировал ассемблерный код для него с помощью-S опции:

Вы тогда будете в состоянии понять, как вызвать функции, аргументы передачи, и т.д.

Nasm/yasm являются Вашим лучшим выбором; gcc встроенный синтаксис вполне наносит вред и может быть очень болезненным для использования время от времени, плюс существуют буквально некоторые вещи, которые это не может делать. Макро-синтаксис Nasm также намного намного более полезен, удача на языке как блок, который не имеет никаких встроенных функций шаблонной обработки.

XCode (т.е. GCC) имеет большую поддержку записи ассемблера. Это - забавная вещь учиться (хотя Вам вряд ли будет нужен он очень), и худшее, которое можно сделать, разрушить программу, которую Вы пишете, то же как в C. Просто Google для 'gcc встраивает учебное руководство по asm x86', и необходимо найти много начальных точек. Не волнуйтесь, что некоторые, будет казаться, будут конкретным Linux, они будут обычно работать точно также в XCode.

(редактирование). принимающее Вас, имеют Intel Mac, конечно; если не тогда заменяют 'x86' 'PPC'.

я запрограммировал блок на Mac. Это был ассемблер Motorola 680x0, использующий MPW. Я затронул ассемблер PowerPC несколько раз в CodeWarrior и ProjectBuilder. Теперь ProjectBuilder называют XCode, и существует Intel. Ассемблер является одним из многих инструментов в XCode.

я первоначально изучил ассемблер на Apple II: 6 502 монитора машинного языка создаются в ROM, мини-ассемблере Sweet16 и других. Позже, я использовал ассемблер Intel 80186 для ускорения медленных битов кода C и работы, оплаченной один дневной курс об ассемблере Intel 80186 в университете. Позже, я должен был поддержать некоторых 680x0 блок для Mac. Это было давным-давно.

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

Нет никакой причины, почему Вы не были должны; нет ничего, что можно сделать в ассемблере, который Вы не можете сделать на высокоуровневом языке как C.

, Насколько инструменты идут, Вы могли бы хотеть установить MacPorts и получить ассемблер GNU. Это может или не может быть самым легким путем, но это свободно, и можно, вероятно, найти учебную документацию для записи программ Unix в ассемблере GNU где-нибудь в сети.

Существуют два три вещи Вы для знания потребности в записи ассемблера в системе с операционной системой (в противоположность блоку 'без операционной системы', который является собственным миром):

, Как система команд работает - загрузки ресурсов для Intel X86, если у Вас есть Intel Mac, все еще разумный набор для PPC, например Внутренности Mac OS X .

, Как собраться, связывают Ваши программы - если Вам установили инструменты Developer, у Вас есть GCC и связанные инструменты

Эта статья предназначена для тех, кто только начинает изучать язык ассемблера. Довольно часто можно встретить книги и статьи с заголовками вроде «Ассемблер это просто». Подобные слоганы — не более чем маркетинговый ход — нужно как-то привлекать клиентов (читателей). Конечно, научиться писать простые программы очень легко. Но все зависит от задач, которые вы перед собой ставите. Научиться водить машину легко. Однако бывает только один водитель-ас.

Подготовка к работе

Думаю, вы уже знакомы с программированием — вы знаете любой из языков высокого уровня (C, PHP, Java, JavaScript и т. д), Вы работали с шестнадцатеричными числами, плюс вы знаете, как использовать командную строку в Windows , Linux или macOS.

На каком процессоре лучше всего учить язык если набор инструкций у всех разный?

Знаете ли вы что такое 8088? Это дедушка всех компьютерных процессоров! И живой дедушка. Я бы сказал — бессмертный и постоянный. Если из вашего процессора, будь то Ryzen, Core i9 или какого-то другого типа, вырвите все застрявшие там гаджеты под влиянием технического прогресса, то старый добрый 8088 останется.

SGX, ММХ, 512-битные регистры SIMD и другие нововведения приходят и уходят.Но дедушка 8088 остался без изменений. Сначала подружитесь с ним. Тогда вы легко справитесь с любыми гаджетами вашего процессора.

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

Какие процессы происходят в процессоре после того, как ты запускаешь программу.

После запуска программного обеспечения и загрузки его операционной системой в ОЗУ процессор обращается к первому байту программы. Выцепляет инструкцию оттуда и выполняет ее, а после ее выполнения переходит к следующей. И так до конца программы.

Некоторые инструкции имеют объем в один байт, а некоторые – в два, три или больше. Это выглядит как то так:

Вернее, даже так:

И только машина способна понять такое. Так что еще несколько лет назад разработчики придумали более гуманный способ общения с компьютером : они создали ассемблер.

С помощью ассемблера можно теперь не танцевать с бубном вокруг шестнадцатерных чисел, а и писать инструкции в мнемонике:

Но ведь и читать-то это намного проще! С другой стороны, если ты увидел ассемблерный код впервые и не знаешь, как его интерпретировать, то такая мнемоника для тебя, скорей всего, тоже будет не ясна.

Зачем нужны регистры процессора и как ими пользоваться.

Какие функции выполняет инструкция Mov ? Присваивает число, которое указано справа, переменной, которая указана слева.

Регистр процессора или ячейка ОЗУ – это одна из переменных в памяти компьютера. Процессор быстрее работает с регистрами, чем с памятью, потому что регистры находятся внутри него. Но у процессора мало регистров, поэтому в любом случае что-то нужно хранить в памяти.

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

У процессора 8088 регистры 16-битные, их восемь штук (в скобках указаны типичные способы применения регистра):

  • AX — общего назначения (аккумулятор);
  • BX — общего назначения (адрес);
  • CX — общего назначения (счетчик);
  • DX — общего назначения (расширяет AX до 32 бит);
  • SI — общего назначения (адрес источника);
  • DI — общего назначения (адрес приемника);
  • BP — указатель базы (обычно адресует переменные, хранимые на стеке);
  • SP — указатель стека.

Хотя каждый регистр имеет типичный вариант использования, вы можете использовать их как хотите. Первые четыре регистра — AX, BX, CX и DX — при желании можно использовать не полностью, а половинками по 8 бит (старший H и младший L): AH, BH, CH, DH и AL, BL, CL, DL. Например, если вы напишете в AX число 0x77AA (mov ax, 0x77AA), то 0x77 попадет в AH, а 0xAA — в AL.

Теория пока закончена. Сейчас мы с тобой подготовим рабочее место и напишем программу «Hello World!» для того, чтобы понять, как эта теория работает на практике.

Подготовка рабочего места

Тебе надо как-то редактировать исходный код. Ты можешь пользоваться любым текстовым редактором, который тебе по душе: Emacs, Vim, Notepad, Notepad++ — сойдет любой. Лично мне нравится редактор, встроенный в Far Manager, с плагином Colorer.

Чтобы в современных ОС запускать программы, написанные для 8088, и проверять, как они работают, тебе понадобится DOSBox или VirtualBox.

Пишем, компилируем и запускаем программу «Hello, world!»

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

Ассемблер для начинающих

Если вы не понимаете, что здесь написано, не волнуйтесь. А пока попробуйте к ассемблерному коду привыкнуть, пощупайте пальцами. Я все объясню ниже. Кроме того, студенческая мудрость гласит: «Ты что-нибудь понимаешь? Перечитал и переписал несколько раз. Сначала непонятное станет знакомым, а потом знакомое станет понятным. «

Для запуска командной строки, в Windows есть cmd.exe. Теперь нужно зайти в папку nasm и скомпилировать программу, используя вот такую команду:

Чтобы запустить этот файл в современной ОС, открой DOSBox и введи туда вот такие три команды:

Ассемблер для начинающих

Инструкции и директивы

В нашей программе есть только три вещи: инструкции, директивы и метки.

Инструкции. Вы уже знакомы с инструкциями (мы рассмотрели их немного раньше) и знаете, что это мнемоника, которую компилятор переводит в машинный код.

Директивы (у нас их две: org и db )- это команды, которые вы даете компилятору. Взятые по отдельности, каждая директива сообщает компилятору, что на этапе сборки необходимо то-то и то-то действие. Директива не переводится в машинный код, но влияет на то, как генерируется машинный код.

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

Директива db указывает компилятору вставить байтовую строку в ваш код. Здесь мы указываем через запятую, что туда помещать. Это может быть строка (в кавычках), символ (в одинарных кавычках) или просто число.

В нашем случае: db "Hello, world", '!', 0 .

Убедитесь, что я вырезал восклицательный знак на остальной части строки, чтобы показать, что вы можете работать с отдельными символами в директиве db. В общем, лучше писать так:

Условные, безусловные переходы и метки

Метки используются для двух целей: для задания имен переменных, которые хранятся в памяти (в нашей программе есть только одна такая метка: string), и для обозначения участков кода, в которых вы переходите из других мест в программе ( В нашем ассортименте три таких лейбла — те, которые начинаются с двух символов-собак).

Что значит «прыгать с других мест в программе»? Процессор обычно выполняет инструкции последовательно, одну за другой. Но если вы хотите организовать ветвление (условие или цикл), вы можете использовать инструкцию ветвления. Вы можете перейти вперед от текущей инструкции или назад.

У тебя в распоряжении есть одна инструкция безусловного перехода ( jmp ) и штук двадцать инструкций условного перехода.

Мы используем две инструкции перехода: je и jmp . Первый выполняет условный переход (Jump if equal — прыгать, если равен), второй (Jump) — безусловный. С их помощью мы организовали цикл.

Обратите внимание, что метки начинаются с буквы, подчеркивания или собаки. Вы также можете вставлять числа, но не в начале. В конце метки необходимо поставить двоеточие.

Выбор регистров, алгоритм и комментарии

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

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

Ассемблер для начинающих

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

  1. Поместить в BX адрес строки.
  2. Поместить в AL очередную букву из строки.
  3. Если вместо буквы там 0, выходим из программы — переходим на 6-й шаг.
  4. Выводим букву на экран.
  5. Повторяем со второго шага.
  6. Конец.

Мы не можем использовать AX для хранения адресной информации, так как нет таких инструкций, которые бы использовали его в качестве регистра-источника.

Данные с клавиатуры

Если программа не может взаимодействовать с пользователем и выполнять его команды, то она бесполезна. Смотри, как можно считывать данные с помощью клавиатуры.Сохрани вот этот код как second.asm.


Потом иди в командную строку и скомпилируй его в NASM:

Затем запусти скомпилированную программу в DOSBox:

Как работает программа? Две строки после метки @@ start вызывают функцию BIOS, которая считывает символы с клавиатуры. Он ожидает, пока пользователь нажмет клавишу, а затем помещает ASCII-код полученного значения в регистр AL. Например, если вы нажмете заглавную A, 0x41 попадет в AL, а если вы нажмете заглавную a, 0x61.

Затем смотрим: если нажата клавиша с кодом 0x1B (клавиша ESC), мы выходим из программы. Если клавиша ESC не нажата, мы вызываем ту же функцию, что и в предыдущей программе, чтобы показать символ на экране. После показа — перейти в начало (jmp): start.

На заметку, инструкция cmp (от слова Compare — сравнивать ) выполняет сравнение, инструкция je(Jump if Equal) – прыжок в конец программы.

Автоматизируем компиляцию и смотрим машинный код

Если тебе интересно, в какой машинный код преобразуются инструкции программы, скомпилируй исходник вот таким вот образом (добавь опцию -l ):

Тогда NASM создаст не только исполняемый файл, но еще и листинг: second.lst . Листинг будет выглядеть как-то так.


Вы, наверное, уже устали вводить длинную последовательность одних и тех же букв в командную строку каждый раз при компиляции. Если вы используете Windows, вы можете создать командный файл (например, m.bat) и вставить в него следующий текст.


Теперь ты можешь компилировать свою программу вот так:

Само собой, вместо first ты можешь подставить любое имя файла.

Выводы

В общем теперь ты знаешь как написать простейшю программе на ассемблере как ее скомпилировать и какие средства для этого нужны. Однако, если ты прочтешь одну статью, то вряд ли станешь настоящим программистом на ассемблере.Чтобы создать и написать на нем что-то действительно стоящее – например, Floppy Bird и “МикроБ”, тебе еще придется немало потрудиться. Но это уже твой первый шаг в этом направлении.

Программирование на языке ассемблера NASM для ОС Unix


Текст этой книги в переработанном виде вошёл в состав "Введения в профессию" в виде третьей части (во втором издании это первый том, в первом издании был второй); небольшие фрагменты материала также вошли в первую (вводную) часть. Переизданий этого материала в виде отдельной книги больше не планируется. Автор настоятельно рекомендует читать Программирование: введение в профессию вместо данной (и сейчас уже устаревшей) книги.

Аннотация

Пособие основано на лекциях, читавшихся автором в рамках курса «Архитектура ЭВМ и язык ассемблера» в Ташкентском филиале МГУ весной 2007 года; часть материала также прошла апробацию в рамках курса «Архитектура ЭВМ и системное программное обеспечение» кафедры Прикладной математики МГТУГА в 2008, 2009 и 2010 гг.

Пособие ориентировано на практические занятия с использованием системы команд i386, «плоской» (бессегментной) модели памяти, ассемблера NASM и операционной системы Linux или FreeBSD; в частности, описываются конвенции системных вызовов обеих систем, также для обеих систем приводятся исходные тексты файлов с макроопределениями, призванными облегчить ассемблерное программирование на ранних этапах изучения дисциплины.

Бумажные публикации

Электронная версия

Статус бумажной версии

Издание поступало в свободную продажу. К настоящему времени полностью распродано.

Прикрепленный файлРазмер
Файл stud_io.inc для FreeBSD2.08 кб
Файл stud_io.inc для Linux2.21 кб
Архив с текстом примера greet из пар. 5.3 (часть II)1.38 кб
Программа cmdl.asm из пар. 4.4 (часть II)1.1 кб
Программа match.asm из пар. 2.6.9 (часть I)1.7 кб

Trailing whitespaces

admin аватар

ах ты ж чёрт

Спасибо

Не знаю почему тут бомбит так у некоторых комментаторов.
Врядли я конечно, когда-нибудь буду писать на ассемблере, но кто знает. Автоу ещё хочется сказать, спасибо, что выложил книгу в открытый доступ. Мне как человеку, который начал интересоваться системным программированием и вообще тем что происходит внутри компьютера было интересно и полезно. Ещё раз спасибо!
Надоели уже эти все современные свителки-перделки, никакой ценности они не несут, не говоря уже о моральных и этических аспектах.

admin аватар

Пожалуйста :-)

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

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

Читаю страницу

Читаю страницу 32:
"Макрос PUTCHAR предназначен для вывода на печать одного символа. Наконец, аргументом этого макроса может выступать исполнительный адрес заключенный в квадратные скобки"

Вот эта программа с посимвольным выводом строки работает правильно:

А вот если раскомментировать две строки (просто исполнительный адрес берется из EDX), вылетает с треском. Где я ошибаюсь?

admin аватар

Очевидно же:

Первая из этих двух команд берёт четыре байта, которые лежат в памяти по адресу string+eax, и кладёт их в edx. Вторая ЭТО использует в качестве адреса, тогда как по смыслу там не адрес вовсе, а первые четыре байта вашей строки. Внимательнее, внимательнее.

Да уж!

Это я не подумавши сделал! )))
Ну, то есть, сначала-то сразу указатель отдавался на разыменование PUTCHAR, а потом добавил транзит через EDX, типа, "какая разница"! Вот она и "разница", бедный указатель разыменовали дважды. А вроде, все просто!
Погорячился, был неправ. Спасибо.

Если вы бы не

Если вы бы не писали сокращенно команды, многое стало бы очевидным и хватало бы времени подумать. Пишите "offset, byte ptr и т.п." и не используйте "mov" для определения адреса ("lea"). Не давайте компилятору повода додумывать за вас что вы написали.

admin аватар

В nasm'е нет ни слова offset, ни этого страшного byte ptr. К большому счастью. Вы бы хотя бы разобрались сначала, о каком ассемблере идёт речь и как он устроен, а потом уже лезли со своими нелепыми советами, особенно насчёт применения lea вместо mov.

Ошибка компоновщика

iMac-OMG-4:Documents Sharab$ nasm -f elf hello.asm
iMac-OMG-4:Documents Sharab$ ld hello.o -o hello
ld: warning: -arch not specified
ld: warning: -macosx_version_min not specified, assuming 10.10
ld: warning: ignoring file hello.o, file was built for unsupported file format ( 0x7F 0x45 0x4C 0x46 0x01 0x01 0x01 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 ) which is not the architecture being linked (x86_64): hello.o
Undefined symbols for architecture x86_64:
"start", referenced from:
implicit entry/start for main executable
ld: symbol(s) not found for inferred architecture x86_64

admin аватар

попробуйте ld -m

попробуйте ld -m elf_i386

Не сработало

iMac-OMG-4:Documents Sharab$ ld -m elf i386
ld: warning: option -m is obsolete and being ignored
ld: file not found: elf
iMac-OMG-4:Documents Sharab$

admin аватар

У меня нет макоси, так что попробовать не могу. Проблема здесь в том, что nasm выдаёт 32-битный код (и в книжке описано программирование именно для 32-битной системы команд), а ваш линкер пытается из этого сделать 64-битное приложение. Естественно, у него ничего не получается. Как ему сказать, чтобы он делал 32-битный исполняемый файл, я не знаю, как не знаю и того, возможно ли это вообще под макосью. Попробуйте на него документацию почитать. Из того, что сходу нашлось в интернете, могу предложить попробовать -arch i386 но не факт, что это поможет.

Nasm под MacOS

"возможно ли это вообще под макосью"

Говорят: "Можно и зайца научить курить, нет ничего невозможного". Если мой заяц не притворяется, MacOS Sierra 10.12.1, nasm 2.12.02, то так:

Ниже - содержимое файла hello1.asm. (Пример hello5.asm к книге так не запустится. Думаю, придется поменять имена, начинающиеся с _ в файле и в stud_io.inc и проверить в stud_io.inc выравнивание стека (кратно 16?))

admin аватар

Прикольно :-)

То есть там конвенция BSD, причём даже 32-битные приложения поддерживаются. Само по себе это прикольно, спасибо за результаты эксперимента, заодно мы теперь знаем, что точка входа там называется start без подчёркивания в начале. Может быть, вы ещё расскажете, как туда Nasm поставить?

Но вот насчёт стека не вполне понятно, когда он, по-вашему, должен быть кратен 16? На момент int 80h? Так он и в вашем примере не кратен. А подпрограмм никаких в stud_io.inc нет.

поставить Nasm на MacOS

>Может быть, вы ещё расскажете, как туда Nasm поставить?

Это не очень детективная история.

stud_io.inc

Да, я имел ввиду "расширение". На линуксе (лубунту) недавно, так что виндовская терминология не отпускает.
С этим файлом разобрался. Книга-супер. Подача материала отличная. Огромная благодарность за сей труд. Понял, что она должна у меня быть в бумажном виде - обязательно пройдусь по книжным магазинам.

За
Версии для Windows нет и не будет.

отдельный респект, свободой веет от неё.

admin аватар

На здоровье

В книжных этой книги нет, единственный вариант сейчас — заказать её на этом сайте, но этот вариант тоже скоро кончится. Книга издавалась тиражом 100 экз., какие там книжные.

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

Добрый вечер.

Добрый вечер. Подскажите, где можно взять файл "stud_io.inc" и в какую папку nasma положить? Пытался на этой странице взять, но куда и с каким разрешением положить не знаю.

admin аватар

Папки - в шкафу

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

Во-вторых, на вопрос "где взять" вы ответили сами. Файл следует взять на этой странице, выше есть ссылка.

В-третьих, чтобы всё сработало, этот файл должен находиться в той же директории, что и ваш файл, который вы транслируете nasm'ом. Вообще-то это довольно очевидно, если внимательно прочитать в книге, как работает макродиректива %include.

Но вот насчёт "с каким разрешением" — на такой вопрос я ответить не могу, я, пардон, даже представить себе не могу, что вы имеете в виду. Если имеется в виду действительно "разрешение", то такая характеристика присуща растровым графическим файлам, видео и (с некоторой натяжкой) аудио, но никак не текстовым файлам. Если имеются в виду "разрешения" (а не "разрешение"), то есть права доступа (один из очень кривых вариантов перевода термина "permissions"), то пользователь, под которым вы работаете, должен иметь права на чтение этого файла, только вряд ли это то, что вы имели в виду. Наконец, можно предположить, что имелось в виду "расширение" (то есть часть имени файла, указывающая на его формат и отделяемая от имени точкой) — в этом случае да будет вам известно, что это пресловутое "расширение" (extension) бывает только под Windows. В *nix-системах используется понятие "суффикс", которое не является однозначно связанным с типом файла и вообще необязательно. В применении к stud_io.inc таким суффиксом, очевидно, является ".inc".

На всякий случай отмечу, что, ежели вам пришло в голову пробовать это всё под виндой, то stud_io.inc вам ничем не поможет — он зависит не только от конкретного набора поддерживаемых операционкой системных вызовов, но и от конкретной конвенции вызовов, именно поэтому для Linux и FreeBSD используются совершенно разные версии. Версии для Windows нет и не будет.

admin аватар

Ещё про 64 бита

Нарылась любопытная ссылочка:

Что-то сдаётся мне, что 64-битные архитектуры идут далеко-далеко лесом, и так ещё лет на десять.

Вот еще

Хочу сказать

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

Инструкция loop

admin аватар

Спасибо!

Про enter/leave я знал, но что это к loop тоже относится, никак не мог предположить. Учту в следующем издании, если таковое когда-нибудь будет.

Скорость инструкций для разных процессоров

admin аватар

Спасибо!

Тоже весьма любопытная ссылочка, thanks!

Mac OS X

А можно ли, и как запустить его на Mac OS X?

admin аватар

Можно-то можно

Что можно — это я не сомневаюсь. Сам NASM представляет собой программу, написанную на ANSI C, так что с его компиляцией и запуском проблем не будет. Более того, вроде бы (если не ошибаюсь) там должны быть те же соглашения о системных вызовах, что и под FreeBSD, потому что в глубине души эта самая Mac OS X и есть FreeBSD :), так что можно будет даже запустить программы, написанные для NASM.

Но вот вопрос "как" здесь вы задаёте явно не по адресу. Я эту вашу макось видел только издали. За шашечки я денег не плачу принципиально, так что ни одного изделия фирмы Apple у меня в хозяйстве нет и никогда не будет (на всякий случай, я не Медведев, так что попытки подарить мне изделие от Apple чревато физическими повреждениями).

Спасибо

Спасибо большое за книгу и Ваш труд.

Выделение памяти

Добрый день, Андрей Викторович.
Могли бы Вы прояснить ситуацию, возникшую в процессе чтения Вашего пособия. Заключается она в следующем: если выделять инициализированную память директивой db (dw, dd), то в параметрах указываются значения через запятую, кот. будут храниться в бинарнике. Если же указать одно значение, например, x db 150, то получается, что выделяется одна ячейка памяти и в эту ячейку памяти заносится байт, принимающий значение 150 (10010110) и x указывает на эту ячейку (точнее ассемблер ассоциирует эту метку с адресом ячейки на этапе ассемблирования). А если бы использовалась директива выделения неинициализированной памяти x resb 150, то здесь выделилась бы память размером в 150 однобайтовых ячеек. Верно? Наставьте, пожалуйста, непонимающего на путь света =). Заранее спасибо.

admin аватар

Абсолютно верно

Вы совершенно правы, а в книге на стр. 50 опечатка. Спасибо за её выявление.

Это Вам

Огроммное

Огроммное спасибо за Вашу книгу!Надо быть действительно прожженным
профи,а также иметь дар Сухомлинского и Макаренко ,что бы в трех
слова объяснить ,что такое указатели.R&K и рядом не валялись.

admin аватар

"Уж сколько раз твердили миру"

Да пожалуйста, мне не жалко :-) А где это вы в моих книгах нашли объяснение указателей? Вроде бы учебника по чистому Си я ещё не написал, да и по Паскалю тоже.

Без розовых очков.

. И где, простите, Sun Microsystems и её SPARC.

SPARC, простите, вот здесь, в первой строчке TOP 500, в суперкомпьютере производительностью порядка десяти петафлоп. Но о задачах, для которых и такой производительности будет мало, Вы, наверное, даже и не слыхали.

admin аватар

Пять минут смеха продлевают жизнь на сутки

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

Насчёт спарков: ну опять вы со своими ракетами. Не волнуют меня суперкомпьютеры, и в особенности меня не волнует top500, представляющий собой бессмысленное мерянье пиписьками, исполняемое, что несколько обидно, за чужой счёт (иногда, замечу, и мой счёт, я ведь тоже налоги плачу). Попадание в верхние позиции top500 означает ровно одно: у кого-то нашлось больше лишних (при этом чужих) денег, чем у других. Вы вот мне скажите, где мне сейчас купить десктоп на спарке, чтобы его на стол поставить, взгромоздить на него тот самый Debian (NB: разумеется, я знаю, на скольких платформах он работает; я, знаете ли, с Linux работаю с 1994 года, а с 1997 — только с ним; больше того, можно было бы заметить, что я и в проекте Openwall участвую, и не только в нём) — так вот, взгромоздить и использовать в качестве рабочего инструмента заместо этого идиотского интела. Что до задач — NASA человека на Луну запустила, обладая совокупной вычислительной мощностью в разы меньшей, нежели мощность современного мобильника. Если программы писать через. ээ. короче, если их как попало писать, то вам любого суперкомпьютера окажется мало. А этот ваш первый в top500 жрёт почти 13 мегаватт, то есть он за месяц одного электричества съедает на сумму, приблизительно соответствующую стоимости строительства многоквартирного дома. Меня это обстоятельство интересует гораздо больше, чем те прожорливые модели, которые на нём обсчитываются.

Книжка Реймонда — она ничего, да (хотя утверждение о том, что pipe — механизм устаревший, поскольку есть сокеты, мне глаз резануло в своё время весьма и весьма). Пару раз я её уже читал, перечитывать в третий раз, пожалуй, всё-таки не стану, некогда. Кстати, вы могли бы и заметить, что в моей книжке 2006 года издания имеются ссылки и на Реймонда, и на Стивенса, и на Танненбаума (хотя его я не люблю, он вечно пишет не о том), и на Торвальдса. Но за язык никто не тянул: берём с полки Реймонда и читаем главу 20. Лучше с карандашиком. Хотя что-то мне сдаётся, что вы сами Реймонда если и открывали, то ни хрена там не увидели.

Но самое занятное, конечно, что вы меня антиглобалистом назвали — вот тут я, извините, долго ржал. Я вообще-то либертарианец, а либертарианство и антиглобализм несовместимы принципиально. Опять же, мою принадлежность к либертарианцам можно было бы установить прямо тут, вот на этом же сайте, из текста вот этого вот сборника. Тьфу.

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

Спасибо за

Спасибо за совет. Учту на будущее.
У меня к Вам есть вопрос по поводу реализации алгоритма временной задержки (таймерной привязки) для процессоров семейства i32, но, скорее всего, это уже частный вопрос, не относящийся к теме. Если у Вас нет времени, или нет желания на всё это -- отпишитесь пожалуйста (на сайте , или на мой почтовый ящик: [email removed]). С уважением, Юрий.
Удачи!

Читайте также: