Скачать 1.99 Mb.
|
org 100h – устанавливает значение программного счётчика в 100h, потому что при загрузке .com-файла в память DOS занимает первые 256 байт блоком данных PSP и располагает код программы только после этого блока. Команда ret используется обычно для возвращения из процедуры. DOS вызывает .com-программы так, что команда ret корректно завершает программу. end start – директивой end завершается любая программа на ассемблере. В качестве необязательного операнда выступает метка(выражение), определяющая адрес, с которого начинается программа. Если программа состоит из нескольких модулей, только один из них может содержать начальный адрес. В данном случае программа оформлена в виде главной процедуры, аналогично функции main в C. Однако тело программы необязательно оформлять в виде процедуры: Листинг 2. model tiny .code org 100h start: <тело программы> ret <данные> <процедуры> end start Существует несколько упрощённый вариант оформления: Листинг 3. model tiny .code .startup <тело программы> .exit [код ошибки] <данные> <процедуры> End .STARTUP по умолчанию генерирует точку входа для .com-файла(модель памяти TINY) в 100h, инициализирует DS, SS, SP в соответствии с выбранной моделью памяти. .EXIT – возврат управления в DOS, аналогично функции DOS 4Ch, в al находится возвращаемый код ошибки.
Программа Hello, world в .exe-формате. Листинг 4. model small .stack .data Msg db 'Hello, world',0Ah,0Dh,'$' .code .startup mov ah,09 lea dx,Msg int 21h mov ax,4C00h int 21h end model small – обычно используется для написания .exe-файлов на ассемблере. .stack – определили сегмент стека размером 1Кб. .data – описали сегмент данных и объявили в нём строку, состоящую из байтов. После апострофа идут управляющие символы, с помощью которых осуществляется переход на следующую строку и символ окончания строки – '$'. mov ax,4C00h int 21h – эквивалентно .exit 0. Листинг 5. Программа(в .exe-формате) преобразования двузначного шестнадцатеричного числа в символьном виде в двоичное представление. Вход: исходное шестнадцатеричное число из двух цифр, вводится с клавиатуры. Выход: результат преобразования должен быть в регистре dl. data segment para public 'data' ;сегмент данных message db 'Введите две шестнадцатеричные цифры,$' data ends stk segment stack db 256 dup ('?') ;сегмент стека stk ends code segment para public 'code' ;начало сегмента кода main proc ;начало процедуры main assume cs:code,ds:data,ss:stk mov ax,data ;адрес сегмента данных в регистр ax mov ds,ax ;ax в ds mov ah,9 mov dx,offset message int 21h xor ax,ax ;очистить регистр ax mov ah,1h ;1h в регистр ah int 21h ;генерация прерывания с номером 21h mov dl,al ;содержимое регистра al в регистр dl sub dl,30h ;вычитание: (dl)=(dl)-30h cmp dl,9h ;сравнить (dl) с 9h jle M1 ;перейти на метку M1 если dl<9h или dl=9h sub dl,7h ;вычитание: (dl)=(dl)-7h M1: ;определение метки M1 mov cl,4h ;пересылка 4h в регистр cl shl dl,cl ;сдвиг содержимого dl на 4 разряда влево int 21h ;вызов прерывания с номером 21h sub al,30h ;вычитание: (dl)=(dl)-30h cmp al,9h ;сравнить (al) с 9h 28 jle M2 ;перейти на метку M2 если al<9h или al=9h sub al,7h ;вычитание: (al)=(al)-7h M2: ;определение метки M2 add dl,al ;сложение: (dl)=(dl)+(al) mov ax,4c00h ;пересылка 4c00h в регистр ax int 21h ;вызов прерывания с номером 21h main endp ;конец процедуры main code ends ;конец сегмента кода end main ;конец программы с точкой входа main Листинг 6. Программа, аналогичная предыдущей, записанная с использованием упрощенных директив определения сегментов. masm ;режим работы TASM: idea1 или masm model sma11 ;модель памяти .data ;сегмент данных message db "Введите две шестнадцатеричные цифры,$" .stack ;сегмент стека db 256 dup ("?") ;сегмент стека .code ;сегмент кода main рrос ;начало процедуры main mov ax,@data ;заносим адрес сегмента данных в регистр ах mov ds,ax ;ах в ds ;далее текст программы идентичен тексту сегмента кода в листинге 3.1 mov ax,4c00h ;пересылка 4c00h в регистр ах int 21h ;вызов прерывания с номером 21h main endp ;конец процедуры main end main ;конец программы с точкой входа main Листинг 7. Пример использования процедуры в программе. model tiny .code org 100h start: mov bl,23h call bcd_ascii ret bcd_ascii proc .186 ;Разрешаем pusha, popa, shr x,4, shl x,4. pusha ;Сохраняем регистры. xor bh,bh ;Обнуляем bh. shl bx,4 ;Сдвигаем bx на четыре бита вправо - в bh shr bl,4 ;находится старшая цифра числа, в bl младшая ;цифра находится в старшем разряде, сдвигаем её ;обратно в младший разряд. or bx,3030h ;Добавляем к цифрам 30h для преобразования в ;ASCII-символ. mov ah,2 ;Выводим на экран. mov dl,bh int 21h mov dl,bl int 21h popa ;Восстанавливаем регистры. ret bcd_ascii endp end start 9h>9h> |