В этой части наконец-то напишем долгожданный «Hello, world!». Теперь почти всё должно быть понятно. Откроем в текстовом редакторе новый файл и сохраним его как hello.asm в директории C:\fasm. Для начала необходимо с помощью директивы db объявить строку, содержащую сообщение «Hello, word!». Лучше сделать это в конце программы, за последней командой, иначе процессор может принять строку за код и попытаться её выполнить.
Для вывода строки используется системная функция DOS. Чтобы напечатать строку, нужно поместить 9 в регистр AH, а в регистр DX поместить адрес строки, которая должна заканчиваться символом ‘$’. Обращение к функциям DOS осуществляется с помощью команды int 21h. Вот код программы:
1 2 3 4 5 6 7 8 9 10 11 | use16 ;Генерировать 16-битный код org 100h ;Программа начинается с адреса 100h mov dx,hello ;В DX адрес строки. mov ah,9 ;Номер функции DOS. int 21h ;Обращение к функции DOS. mov ax,4C00h ;\ int 21h ;/ Завершение программы ;------------------------------------------------------- hello db 'Hello, world!$' |
В четвёртой строке FASM подставит адрес строки вместо hello. Не трудно догадаться, что завершение программы — это тоже функция DOS с номером 4Ch. Перед её вызовом в регистр AL помещается код завершения программы (ноль соответствует успешному завершению). Можно объединить эти две операции и сразу поместить в AX значение 4C00h.
В учебном курсе я не буду подробно описывать функции DOS, лишь кратко расскажу о тех функциях, которые мы будем использовать. Если вы захотите узнать больше, в Интернете можно найти подробное описание
Чтобы увидеть работу программы, надо дать команду fasm для компиляции исходного кода в файл COM, а затем запустить её из командной строки DOSBox.
Если вы помните, в третьем уроке про отладчик мы разбирали нашу первую программу в дебагере. Для работы дебагера мы редактировали dosbox.conf, чтобы закоментировать DPMI хост. Теперь нам нужно снова вызвать хост и раскомменировать эти две строки:
1 2 | #cd CWSDPMI/BIN/ #CWSDPMI -p -s- |
Уберите знаки решетки в начале строк и сохраните dosbox.conf. Теперь запускаем DOSBox и вводим команды:
1 2 | fasm hello.asm hello.com |
Результат работы программы:
Если вы запустите программу в отладчике Turbo Debugger, то просмотреть выводимую строку можно, нажав Alt+F5 или выбрав в меню Turbo Debugger пункт Window->User Screen.
5 ответов к “Учебный курс. Урок 6. Hello, world!”
не знаю, сколько времени затрачено на поиск, но гугл завел меня на этот сайт и именно то, что нужно!
Прочитал 6 уроков, наконец есть какой-то вывод на экран. Еще интересует, будут ли уроки про непосредственную работу с «железом»?
В планах написание нескольких уроков на тему портов ввода/вывода. Также на тему прерывания. К слову, любые манипуляции с железом из под windows — это только эмуляция прямого обращения к железу из-за особенностей ОС. Ну и лишних знаний не бывает. Программирование под МК на ассемблере будет включать массу всевозможных прерываний и обращений к ножкам ввода/вывода. Работа с МК это другой ассемблер, но суть та же.
Здравствуйте, все понятно, но хотелось-бы узнать, как можно перезаписать в переменную другое значение?
Я пытался, при компиляции выдал ошибку, что такая уже есть. И ещё, как обращаться к функциям DOS(int 21h) повторно? При попытке вывести переменную на экран второй раз, программа ничего не пишет и не завершается. Ответьте пожалуйста на оба вопроса)
Добрый день :)
В нашем случае команда mov пожет за один вызов перезаписать только один байт строки по указанному адресу. То есть чтобы переписать значение в строке по её адресу в памяти, нужно будет пройти каждый байт от адреса начала строки и поместить туда новое значение:
mov [hello],10 ;Cпецсимвол ASCII переноса строки
mov [hello+1],13 ;Спецсимвол ASCII возврата каретки
mov [hello+2],'L'
mov [hello+3],'a'
mov [hello+4],'m'
mov [hello+5],'p'
mov [hello+6],'$' ;Обязательно указываем на завершение строки.
int 21h ;Обращение к функции 0x9 DOS.
Ну а куда проще объявить еще одну переменную с другой строкой:
...
mov dx,hello ;В DX адрес строки.
mov ah,0x9 ;Номер функции DOS.
int 21h ;Обращение к функции DOS.
mov dx,hello1 ;В DX адрес новой строки строки.
int 21h ;Обращение к функции DOS 0x9.
...
hello1 db 10,13,'Lamp$' ;Последовательность 10,13 - перенос строки и возврат каретки.