assembler hello world
На c++ так же, как и на «Си». Во всех современных компиляторах есть ключ «вывести ассемблерный листинг». Поглядите документацию к Вашему компилятору, поставьте этот ключ и получите ассемблерный листинг.
26 ноя 2019 в 8:18
ааа! и типо для оптимизации что то поудалать?
27 ноя 2019 в 4:47
1 ответ 1
Сортировка: Сброс на вариант по умолчанию
- Набор регистров зависит от архитектуры процессора, а не от операционной системы. Для большинства десктопных компьютеров это x86. Если вы пишете под архитектуру x86, то доступный набор регистров и команд будет примерно одним и тем же. А вот программный интерфейс (API, грубо говоря набор доступных функций ОС) и бинарный интерфейс (ABI, грубо говоря способ вызова функций API и способ передачи параметров) для разных систем, разной «битности» — будут разными.
- Я нашел такой пример (Linux, x86-64):
.data msg: .ascii "Hello, world!\n" .set len, . - msg .text .globl _start _start: # write mov $1, %rax mov $1, %rdi mov $msg, %rsi mov $len, %rdx syscall # exit mov $60, %rax xor %rdi, %rdi syscall
Собирается так:
as --64 hello-syscall.s -o hello-syscall.o ld -melf_x86_64 -s hello-syscall.o -o hello-syscall
Отслеживать
ответ дан 25 ноя 2019 в 6:01
48.6k 17 17 золотых знаков 56 56 серебряных знаков 100 100 бронзовых знаков
- ассемблер
- gnu-assembler
-
Важное на Мете
Похожие
Подписаться на ленту
Лента вопроса
Для подписки на ленту скопируйте и вставьте эту ссылку в вашу программу для чтения RSS.
Дизайн сайта / логотип © 2024 Stack Exchange Inc; пользовательские материалы лицензированы в соответствии с CC BY-SA . rev 2024.1.9.3159
Нажимая «Принять все файлы cookie» вы соглашаетесь, что Stack Exchange может хранить файлы cookie на вашем устройстве и раскрывать информацию в соответствии с нашей Политикой в отношении файлов cookie.
Hello World на Ассемблере
После примеров простых программ на Паскале и С++ вы, наверно, не ожидали что я сразу перепрыгну на Ассемблер. Но вот перепрыгнул. И сегодня мы поприветствуем мир на языке ассемблера.
Итак, вот сразу пример, а потом его рассмотрим:
.model tiny .code ORG 100h begin: MOV AH, 9 ; Функция вывода строки на экран MOV DX, OFFSET Msg ; Адрес строки INT 21h ; Выполнить функцию RET ; Вернуться в операционную систему Msg DB 'Hello, World. $' ; Строка для вывода END begin
Как видите, программа на ассемблере, даже такая простая, содержит исходный текст значительно большего размера по сравнению с аналогичной программой на С++, а уж тем более на Паскале.
С другой стороны, это не так уж и страшно, как иногда думают те, кто никогда не программировал на Ассемблере.
Во всех подробностях разбирать этот код не будем — подробности в другой раз. Рассмотрим только основные инструкции.
Программа начинается с метки begin . В отличие, например, от Паскаля, это слово может быть каким угодно, например, start . Это всего лишь метка, которая обозначает начало какого-то участка кода.
К конце программы мы видим END begin . Инструкция END говорит ассемблеру, что следующее за ней слово означает конец блока кода, обозначенного этим словом. В нашем примере это означает, что здесь кончается блок кода, начинающийся со слова begin .
Далее уже начинается программа. Сначала в регистр АН мы записываем номер функции, которую собираемся потом выполнить. Номер 9 — это функция BIOS, которая выполняет вывод на устройство вывода. По умолчанию это монитор.
Затем в регистр DX мы записываем адрес строки. Адрес вычисляется с помощью оператора OFFSET . Например:
Здесь мы получаем адрес первого байта блока данных, обозначенного идентификатором Msg .
Затем мы вызываем прерывание 21h . Это прерывание выполняет функцию, номер которой записан в регистре АН. Поскольку у нас там записана функция 9, то прерывание выведет на экран строку.
Команда RET выполняет выход из процедуры или из программы. В нашем случае из программы. Таким образом программа завершается и мы возвращаемся в операционную систему.
Ещё несколько слов об объявлении строки:
Msg DB ‘Hello, World. $’
Вначале мы записываем идентификатор (в нашем случае Msg , но может быть и любой дугой), чтобы было проще работать со строкой. Затем пишем DB — Define Byte — Определить Байт. В нашем случае это будет массив байтов, в котором каждый элемент имеет размер один байт.
Потом пишем саму строку. Каждый символ занимает один байт, поэтому мы и объявили массив байтов. Знак доллара означает конец строки. Так функция вывода понимает, где она должна завершить вывод. Если этот знак не поставить, то будет выведено множество символов — сначала наша строка, а потом разный мусор, содержащийся в ячейках памяти, следующих за нашей строкой. А в эмуляторах это вообще может считаться ошибкой и вывода не будет.
Ну вот мы и написали свою первую программу на языке ассемблера. Если что-то пропустили, то посмотрите видео:
Как вывести строку на экран в Ассемблере
Что бы ни делала ваша программа, в большинстве случаев она должна выводить какие-то данные на экран. И если в языках высокого уровня это делается “лёгким движением руки”, то в ассемблере для этого приходится как следует помучиться.
Правда, в современных воплощениях языка Ассемблера могут быть стандартные макросы или подпрограммы для вывода строк на экран. Однако начинающим будет полезно разобраться с тем, как это можно сделать только с помощью инструкций, без применения каких-либо облегчающих жизнь библиотек.
Итак, выводить строки на экран можно двумя путями:
- Посимвольно (то есть в цикле выводить каждый символ строки).
- Строку целиком.
Кроме того, в текстовом режиме вывод на экран можно выполнить одним из трёх способов:
- С помощью функций DOS.
- С помощью функций BIOS.
- Путём прямой записи в видеопамять.
Третий способ хорош тем, что он сразу записывает данные в видеопамять, что позволяет выполнять вывод более быстро. Однако в наше время он применим, разве что, в учебных целях. Потому что современные операционные системы не позволяют напрямую обращаться к “железу”.
Поэтому, если ваша программа является чуть более, чем учебной, то придётся применять один из первых двух способов. Ну а если вам интересно, как выполнить вывод непосредственно в видеопамять, то посмотреть примеры вы можете здесь или здесь.
Функции вывода DOS
Итак, начнём с функций вывода DOS. Эти функции являются функциями операционной системы DOS, но поддерживаются и операционными системами Windows.
Как я уже говорил, можно напечатать на экране строку в цикле, отдельно выводя каждый символ. Для этих целей можно использовать функции 02h, 06h или недокуметированное прерывание 29h.
Если требуется вывести на экран строку целиком, то можно применить функции 09h и 40h.
Для использования функций DOS надо сначала подготовить необходимые данные, записать номер функции в регистр AH, а затем вызвать прерывание 21h.
Все функции рассматривать здесь не будем. Для примера используем одну из самых простых функций DOS — функцию 09h, которая выводит в стандартное устройство вывода (в нашем случае — на экран) строку, адрес которой находится в DS:DX. Строка должна заканчиваться символом $, иначе функция не поймёт, где конец строки, и программа будет выводить много-много символов из памяти, начиная с указанного адреса. Примерно так, как показано на рисунке:

;========================================================== ; Эта программа выводит на экран строку "Hello, World. " ; с помощью функции DOS 09h ;---------------------------------------------------------- .model tiny .code ORG 100h ;начало СОМ-файла start: MOV AH, 09h ;Номер функции 09h MOV DX, offset stroka ;Адрес строки записываем в DX INT 21h RET ;завершение СОМ-файла stroka DB 'Hello, World. $' ;Строка для вывода END start ;==========================================================
При правильном использовании на экран будет выведено примерно следующее:

Функции вывода BIOS
Функции BIOS также могут выводить как отдельные символы (функции 09h, 0Ah, 0Eh), так и строки целиком (функция 13h).
Кроме того с помощью функций BIOS можно установить видеорежим, установить или считать положение курсора, а также считать символ и его атрибуты.
Хотя функции DOS тоже могут считывать символы, но всё-таки возможности BIOS более широки.
Для работы с функциями BIOS также сначала надо подготовить данные, записать номер функции в регистр AH, а затем вызвать прерывание 10h.
Для примера рассмотрим функцию 13h. Перед вызовом функции надо:
- Записать номер функции в регистр АН.
- Записать режим вывода в регистр AL:
- бит 0: переместить курсор в конец строки после вывода.
- бит 1: строка содержит не только символы, но и атрибуты. Так что каждый символ описывается двумя байтами — ASCII-код и атрибут. Это можно использовать, если в строке символы должны иметь, например, разный цвет. Если атрибуты одинаковы для всей строки, то этот бит лучше сбросить (обнулить).
- биты 2-7: не используются.
;========================================================== ; Эта программа выводит на экран строку "Hello, World. " ; с помощью функции BIOS 13h ;---------------------------------------------------------- .model tiny .code ORG 100h ;начало СОМ-файла start: MOV AH, 13h ;Номер функции 13h MOV AL, 1 ;Перевести курсор в конец строки MOV CX, 15 ;Длина строки MOV BL, 00011110b ;Жёлтый текст на синем фоне MOV DL, 5 ;Координата Х MOV DH, 2 ;Координата Y MOV BP, offset stroka ;Адрес строки записываем в DX INT 10h RET ;завершение СОМ-файла stroka DB 'Hello, World. ' ;Строка для вывода END start ;==========================================================

Рассказывать об остальных функциях, а также об установке атрибутов и прочих вещах сегодня не буду. Если кому интересно, то всё это можно найти в справочных материалах.
Art1xFX / lab2masm.asm
Разработать программу вывода строки “Hello World” на экран в стилях masm и tasm с использованием директивы db определить в сегменте данных строку ‘Hello World’,10,13,’$’. Инициализировать регистр ds адресом сегмента данных. С помощью функции 9 прерывания 21h вывести эту строку на экран.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
.MODEL SMALL ;Модель памяти .DATA ;Сегмент данных MESSAGE DB «Hello World» , 10 , 13 , ‘$’ .CODE ;Сегмент кода MAIN: ;Точка входа в приложение MOV AX , @DATA ;Инициализация сегмента данных MOV DS , AX ;Через регистр AX MOV AH , 9H ;Вывод строки на экран MOV DX , OFFSET MESSAGE ;находящейся по адресу в DX INT 21H ;до символа $ MOV AH , 4CH ;Завершение программы INT 21H END MAIN