Привет всем) Ребят вот в чем проблемма: пребод дал задание решить пример и написать решения на ассемблере. Вот пример: (20+9)-(6+4)-3 Вот код расчета:
mov dl,20 mov al,9 add dl,al mov bh,6 mov ah,4 add bh,ah sub bh,bl mov bl,3 sub dl,bh
Вот код вывода:
mov dl,20 mov al,9 add dl,al mov bh,6 mov ah,4 add bh,ah sub bh,bl mov bl,3 sub dl,bh mov bx,0 mov bl,al push -1 mov cx,10 l:mov dx,0 div cx push dx cmp ax,0 jne l mov ah,2h l2:pop dx cmp dx,-1 je ex add dl,’0′ int 21h ex:mov ax,4c00h int 21h end start
Вот весь код:
; multi-segment executable file template. data segment ; add your data here! pkey db «press any key. $» ends stack segment dw 128 dup(0) ends code segment start: ; set segment registers: mov ax, data mov ds, ax mov es, ax mov dl,20 mov al,9 add dl,al mov bh,6 mov ah,4 add bh,ah sub bh,bl mov bl,3 sub dl,bh mov bx,0 mov bl,al push -1 mov cx,10 l:mov dx,0 div cx push dx cmp ax,0 jne l mov ah,2h l2:pop dx cmp dx,-1 je ex add dl,’0′ int 21h ex:mov ax,4c00h int 21h end start
Подозреваю что ошибка в коде вывода — невыдает нужное число, а выдает 9 или 1. Помогите плиз)))
ЯЗЫК АССЕМБЛЕРА за 3 МИНУТЫ
Источник: studassistent.ru
Emu8086
Если вы скачали и установили эмулятор процессора 8086 (см. раздел ВВЕДЕНИЕ), то вы можете использовать его для создания ваших первых программ на языке ассемблера. На текущий момент (ноябрь 2011 г) доступна версия программы 4.08. Справку на русском языке вы можете найти здесь: Справка Emu8086.
Программа Emu8086 платная. Однако в течение 30 дней вы можете использовать её для ознакомления бесплатно.
Итак, вы скачали и установили программу Emu8086 на свой компьютер. Запускаем её и создаём новый файл через меню FILE – NEW – COM TEMPLATE (Файл – Новый – Шаблон файла COM). В редакторе исходного кода после этого мы увидим следующее:
Рис. 1.1. Создание нового файла в Emu8086.
Здесь надо отметить, что программы, создаваемые с помощью Ассемблеров для компьютеров под управлением Windows, бывают двух типов: COM и EXE. Отличия между этими файлами мы рассмотрим позже, а пока вам достаточно знать, что на первое время мы будем создавать исполняемые файлы с расширением COM, так как они более простые.
После создания файла в Emu8086 описанным выше способом в редакторе исходного кода вы увидите строку «add your code hear» — «добавьте ваш код здесь» (рис. 1.1). Эту строку мы удаляем и вставляем вместо неё следующий текст:
MOV AH, 02h MOV DL, 41h INT 21h INT 20h
Таким образом, полный текст программы будет выглядеть так:
ORG 100h MOV AH, 02h MOV DL, 41h INT 21h INT 20h RET
Кроме этого в верхней части ещё имеются комментарии (на рис. 1.1 – это текст зелёного цвета).
ЯЗЫК АССЕМБЛЕРА С НУЛЯ | #1 НАЧАЛО
Комментарий в языке Ассемблера начинается с символа ; (точка с запятой) и продолжается до конца строки. Если вы не знаете, что такое комментарии и зачем они нужны, см. книгу Как стать программистом. Как я уже говорил, здесь мы не будем растолковать азы программирования, так как книга, которую вы сейчас читаете, рассчитана на людей, знакомых с основами программирования.
Также отметим, что регистр символов в языке ассемблера роли не играет. Вы можете написать RET, ret или Ret – это будет одна и та же команда.
Вы можете сохранить этот файл куда-нибудь на диск. Но можете и не сохранять. Чтобы выполнить программу, нажмите кнопку EMULATE (с зелёным треугольником) или клавишу F5. Откроется два окна: окно эмулятора и окно исходного кода (рис. 1.2).
Рис. 1.2. Окно эмулятора Emu8086.
В окне эмулятора отображаются регистры и находятся кнопки управления программой. В окне исходного кода отображается исходный текст вашей программы, где подсвечивается строка, которая выполняется в данный момент. Всё это очень удобно для изучения и отладки программ. Но нам это пока не надо.
В окне эмулятора вы можете запустить вашу программу на выполнение целиком (кнопка RUN) либо в пошаговом режиме (кнопка SINGLE STEP). Пошаговый режим удобен для отладки. Ну а мы сейчас запустим программу на выполнение кнопкой RUN. После этого (если вы не сделали ошибок в тексте программы) вы увидите сообщение о завершении программы (рис. 1.3).
Здесь вам сообщают о том, что программа передала управление операционной системе, то есть программа была успешно завершена. Нажмите кнопку ОК в этом окне и вы увидите, наконец, результат работы вашей первой программы на языке ассемблера (рис. 1.4).
Рис. 1.3. Сообщение о завершении программы.
Рис. 1.4. Ваша первая программа выполнена.
Как мы уже говорили, наша первая программа выводит на экран английскую букву «А». Результат оправдал наши ожидания – буква «А» выведена на экран.
Здесь стоит отметить, что Emu8086 – это ЭМУЛЯТОР, то есть он эмулирует работу компьютера с процессором 8086. Поэтому в описанном выше примере программа выполняется не операционной системой, а эмулятором. Emu8086 может создавать и реальные программы, которые могут самостоятельно выполняться на компьютере. Но описание работы с Emu8086 не входит в наши планы. Читайте справку и экспериментируйте – всё у вас получится.
В нашем случае пока не важно, как выполняется программа – эмулятором или операционной системой. Главное – разобраться с вопросом создания программ на языке ассемблера. Поэтому разберём нашу простенькую программку подробно.
#make_COM# – 1-ая строка. Эта команда – специфическая для Emu8086. Она используется для определения типа создаваемого файла. В нашем случае это файл с расширением .COM.
ORG 100h – 2-ая строка. Эта команда устанавливает значение программного счетчика в 100h, потому что при загрузке СОМ-файла в память, DOS выделяет под блок данных PSP первые 256 байт (десятичное число 256 равно шестнадцатеричному 100). Код программы располагается только после этого блока. Все программы, которые компилируются в файлы типа СОМ, должны начинаться с этой директивы.
MOV AH, 02h – 3-я строка. Инструкция (или команда) MOV помещает значение второго операнда в первый операнд. То есть значение 02h помещается в регистр АН. Для чего это делается? 02h – это ДОСовская функция, которая выводит символ на экран.
Мы пишем программу для DOS, поэтому используем команды этой операционной системы (ОС). А записываем мы эту функцию (а точнее ее номер) именно в регистр АН, потому что прерывание 21h использует именно этот регистр.
MOV DL, 41h – 4-я строка. Код символа «A» заносится в регистр DL. Код символа «A» по стандарту ASCII – это 41h.
INT 21h – 5-я строка. Это и есть то самое прерывание 21h – команда, которая вызывает системную функцию DOS, заданную в регистре АН (в нашем примере это функция 02h). Команда INT 21h – основное средство взаимодействия программ с ОС.
INT 20h – 6-я строка. Это прерывание, которое сообщает операционной системе о выходе из программы и о передаче управления консольному приложению. Значит, при использовании INT 20h в нашем примере, управление будет передаваться программе Emu8086. А в том случае, если программа уже откомпилирована и запущена из ОС, то команда INT 20h вернет нас в ОС (например, в DOS).
В принципе, в случае с Emu8086 эту команду можно было бы пропустить, так как эту же функцию выполняет команда RET, которая вставляется в исходный текст автоматически при создании нового файла по шаблону (как это сделали мы ранее). Но я решил использовать INT 20h и здесь для совместимости с другими ассемблерами.
Тем, кому не все понятно из этих объяснений, рекомендую почитать книгу Как стать программистом, а также следующие главы.
Источник: av-assembler.ru
Формат строки
Метки — это имена, использующиеся в программе для ссылки на числа и строки символов или ячейки памяти. Метки позволяют присваивать имена переменным в памяти, значениям и адресам, где находятся конкретные инструкции. Например: dseg SEGMENT ‘DATA’ FactorialValue DW ? Factorial DW ? dseg ENDS cseg SEGMENT ‘CODE’ ASSUME CS: cseg, DS: dseg FiveFactorial PROC start: MOV AX, dseg MOV DS, AX MOV [FactorialValue], 1 3
Определения меток в коде программы (и содержащиеся на отдельной строке, и после которых на той же строке следуют директивы или инструкции) должны заканчиваться двоеточием (:). Двоеточие просто завершает метку и не является ее частью. Например, в следующем фрагменте программы: LoopTop: mov al,[si] inc si and al,al jz Done jmp LoopTop Done: ret метки LoopTop и Done определены с двоеточиями, но в ссылках на эти метки двоеточия не указываются. Другие метки в общем случае не должны завершаться двоеточием. В примере программы в начале данной лабораторной работы содержатся несколько меток без двоеточий.
Мнемоники команд и директивы
Основным полем в строке программы на Ассемблере является поле <команда/директива>. Это поле может содержать мнемонику команды или директиву. Команды непосредственно выполняются процессором i8086. Ассемблер компилирует каждую мнемонику команды непосредственно в соответствующую команду на машинном языке. В отличие от мнемоник команд, директивы не генерируют выполняемого кода. Вместо этого они управляют различными аспектами работы Ассемблера — от типа ассемблируемого кода до используемых сегментов и формата создаваемых файлов листингов и т. д.
Директивы Ассемблера
Директива SEGMENT используется для того, чтобы начать сегмент. Каждой директиве SEGMENT должна соответствовать директива ENDS, завершающая сегмент. Полная форма директивы SEGMENT имеет следующий вид: имя SEGMENT выравнивание комбинирование использование ‘класс’ где поля «выравнивание», «комбинирование», «использование» и «класс» необязательны 1 . Поле «имя» задает имя сегмента.
Имена сегментов являются метками, поэтому в своих исходных модулях они должны быть уникальны. При завершении сегмента то же имя должно использоваться в директиве ENDS. Пример: 1 См. Приложение 1. 5
cseg SEGMENT . cseg ENDS Сегменты могут быть вложенными, что означает, что можно определить сегмент до того, как закончится предыдущий сегмент, например: DataSeg SEGMENT PARA PUBLIC ‘DATA’ . DataSeg2 SEGMENT PARA PRIVATE ‘FAR_DATA’ . DataSeg2 ENDS . DataSeg ENDS Директива ENDS определяет конец сегмента. Например: cseg ENDS завершает сегмент с именем cseg , который начинался по директиве SEGMENT.
При использовании стандартных директив определения сегментов необходимо явным образом завершать каждый сегмент. Директива ASSUME позволяет сообщить Ассемблеру, на какой сегмент или группу указывает данный сегментный регистр. Это не то же самое, что действительная загрузка сегментного регистра для ссылки на данный сегмент (это необходимо делать отдельно с помощью инструкции MOV).
Назначение директивы ASSUME состоит в том, чтобы дать Ассемблеру возможность проверить допустимость ссылок на память и при обращении к памяти автоматически включить префиксы переопределения сегментов (если это требуется). Директива ASSUME для регистра CS должна следовать перед любым кодом в каждом исходном модуле.
Благодаря этому Ассемблер знает, в каком сегменте подразумевается размещение инструкций 1 . Пример директивы ASSUME: DataSeg SEGMENT PARA PUBLIC ‘DATA’ . DataSeg ENDS CodeSeg SEGMENT PARA PUBLIC ‘CODE’ ASSUME CS:CodeSeg,DS:DataSeg . CodeSeg ENDS Директива END. Каждая программа должна содержать директиву END, отмечающую конец исходного кода программы. Все строки, которые следуют за директивой END, Ассемблером игнорируются.
Если 1 По мере необходимости в любой исходный модуль могут включаться другие директивы ASSUME (с указанием различных сегментных регистров). Подразумеваемый сегмент для любого сегментного регистра может быть изменен, когда это необходимо. В одной директиве ASSUME можно изменить любой или все сегментные регистры. 6
опустить директиву END, то генерируется ошибка, поэтому необходимо всегда указывать директиву END. Например: sseg SEGMENT ‘STACK’ DB 200h DUP (?) sseg ENDS dseg SEGMENT ‘DATA’ . dseg ENDS cseg SEGMENT ‘CODE’ ASSUME CS: cseg, DS: dseg, SS: sseg start: MOV AX, dseg MOV DS, AX MOV AH, 4ch INT 21h cseg ENDS END start Это простейшая программа на Ассемблере. Она ничего не делает, просто немедленно возвращает управление DOS.
На одной строке с директивой END содержится метка start . Кроме завершения программы, директива END может выполнять еще и вторую функцию, указывая, где должно начинаться выполнение при запуске программы. Иногда требуется начать выполнение программы в файле .EXE не с первой команды. Директива END предусматривает такие случаи. Пример: sseg SEGMENT ‘STACK’ DB 200h DUP (?) sseg ENDS dseg SEGMENT ‘DATA’ . dseg ENDS cseg SEGMENT ‘CODE’ ASSUME CS: cseg, DS: dseg, SS: sseg Delay: MOV CX, 40 DelayLoop: LOOP DelayLoop RET start: MOV AX, dseg MOV DS, AX CALL Delay MOV AH, 4ch INT 21h 7
Источник: studfile.net