Поиск:

Ответ в темуСоздание новой темы Создание опроса
> ASM - с чего начать? 
:(
    Опции темы
Wowa
Дата 25.3.2002, 01:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
Group Icon


Профиль
Группа: Админ
Сообщений: 15017
Регистрация: 14.9.2000
Где: Винград

Репутация: нет
Всего: 290



Посоветуйте что-нибудь.
PM WWW   Вверх
Fantasist
Дата 25.3.2002, 07:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Лентяй
***


Профиль
Группа: Участник Клуба
Сообщений: 1517
Регистрация: 24.3.2002

Репутация: нет
Всего: 41



Chingachguka! Chingachguka на сцену. Пусть дла начала свои уроки запостит.


--------------------
Волны гасят ветер...
PM MAIL   Вверх
Vit
Дата 25.3.2002, 11:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Vitaly Nevzorov
****


Профиль
Группа: Экс. модератор
Сообщений: 10964
Регистрация: 25.3.2002
Где: Chicago

Репутация: нет
Всего: 207



Это точно, начинать надо с Chingachguka :)


--------------------
With the best wishes, Vit
I have done so much with so little for so long that I am now qualified to do anything with nothing
Самый большой Delphi FAQ на русском языке здесь: www.drkb.ru
PM MAIL WWW ICQ   Вверх
neutrino
  Дата 25.3.2002, 12:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Gothic soul
****


Профиль
Группа: Модератор
Сообщений: 3041
Регистрация: 25.3.2002
Где: Верхняя Галилея, Кармиэль

Репутация: нет
Всего: 62



Est takaia bolshaia kniga Toma Svana (Tom Swan) nazivaetsia "programmirovanie v Turbo Assembler". Ochen podrobnoe opisanie. Kucha primerov i poniatno napisannaia.
Rekomenduiu. :)


--------------------
The truth comes from within ...

Покойся с миром, Vit 
PM MAIL WWW ICQ Skype GTalk   Вверх
Chingachguk
Дата 25.3.2002, 17:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1232
Регистрация: 25.3.2002
Где: Москва

Репутация: 11
Всего: 18



О ! Всем привет ! ;)))

Так что, можно продолжить ?! Оки !
Ниже пошел первый Урок.


--------------------
I don't like the drugs (but the drugs like me). M.Manson.
PM MAIL ICQ   Вверх
Chingachguk
Дата 25.3.2002, 17:39 (ссылка) |    (голосов:2) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1232
Регистрация: 25.3.2002
Где: Москва

Репутация: 11
Всего: 18



Урок 1. Немного порисуем.

Итак, начнем. Запустите tp7(или более младшие версии,
где можно писать asm end; - и компиллер не ругнется).
Tp7 Вы можете взять тут(~550Кил):
http://chat.ru/~vzubko/tp7.zip

Наберите следующий код:

begin
 {Устанавливаем графический режим монитора 13h, 320x200, 256 цветов}
 asm
 mov  ax,0013h
 int  10h
 end;
 asm
 mov  ax,0A000h
 mov  es,ax
 {Рисуем - раз}
 mov  byte ptr es:[320*10+10],12
 mov  byte ptr es:[320*10+11],12
 mov  byte ptr es:[320*10+12],12
 mov  byte ptr es:[320*11+10],12
 mov  byte ptr es:[320*11+11],12
 mov  byte ptr es:[320*11+12],12
 mov  byte ptr es:[320*12+10],12
 mov  byte ptr es:[320*12+11],12
 mov  byte ptr es:[320*12+12],12
 {Рисуем - два}
 mov  byte ptr es:[320*100+100],1
 mov  byte ptr es:[320*101+101],2
 mov  byte ptr es:[320*102+102],3
 mov  byte ptr es:[320*103+103],4
 mov  byte ptr es:[320*104+104],5
 mov  byte ptr es:[320*105+105],6
 end;
 {Ожидаем нажатия клавиши}
 asm
 mov  ah,0
 int  16h
 end;
 {Устанавливаем текстовый режим монитора 03h, 80x25, 16 цветов текста и фона}
 asm
 mov  ax,0003h
 int  10h
 end;
end.

Ага. Теперь скомпиллируйте ЭТО и запустите на выполнение. Что Вы видите ?
(Должны увидеть квадратик и цепочку точек). Нажав клавишу, Вы должны закрыть
графическое окно и вернуться в среду.

НЕбольшое техническое отступление. Синтаксис асм-вставок в tp7.
Асм-вставка начианется псевдооператором "asm". Далее идут сами ассемблерные
команды(Вы должны видеть их зелеными). Завешает блок асм директива
"end;" - как, врочем, и другие логически завершенные блоки в Pascal.

Теперь посмотрим на команды. Их не так много и они довольно одинаковы.
Отбросим пока вот эти три блока, дав им поверхностное объяснение:

 asm
 mov  ax,0013h
 int  10h
 end;

Пока примите, как факт, что для вызова Операционной системы, BIOS или
других программ обычно используются вот такие вот записи(команды):

 mov ax,0013h - это пример ЗАДАНИЯ ПАРАМЕТРОВ, передаваемых другим
программам;
 int 10h - это ВЫЗОВ других программ Вашей машины - здесь это вызов BIOS.

 {Ожидаем нажатия клавиши}
 asm
 mov  ah,0
 int  16h
 end;

 mov ah,0 - это пример ЗАДАНИЯ ПАРАМЕТРОВ, передаваемых другим
программам;
 int 16h - это ВЫЗОВ других программ Вашей машины - здесь это вызов BIOS.

Итак, вернемся к тем командам, которые откомментарены как " {Рисуем - раз}"
и "{Рисуем - два}". Попытайтесь понять, чем они похожи, а чем отличаются...

... Вы должны были заметить, что вот эти команды:

 mov  byte ptr es:[320*10+10],12
 mov  byte ptr es:[320*10+11],12
 ...

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

mov byte ptr es:[Что-то],Еще что-то.

Попробуйте самостоятельно поменять эти "Что-то" и "Еще что-то" у нескольких
команд. Посмотрите на результат. Создайте еще несколько подобных  команд.
Проявите фантазию в разумных пределах и насоздавайте еще разных
подобных команд.
Попытайтесь сделать самостоятельно какие-то обобщения по результатам.

А теперь небольшое задание. Исходный пример рисовал нам красный квадратик в
верхнем левом углу экрана. Попробуйте на основе полученного опыта ТОЛЬКО с
помощью команд типа:

mov byte ptr es:[Что-то],Еще что-то.

нарисовать синий прямоугольник, но уже в нижнем правом углу экрана.
Подсказка: обратите внимание вот на этот комментарий:

{Устанавливаем графический режим монитора 13h, 320x200, 256 цветов}

Урок 1 закончен. Решение и некоторые объяснения будут даны в
уроке 2. Да пребудет с Вами Великая Сила !


--------------------
I don't like the drugs (but the drugs like me). M.Manson.
PM MAIL ICQ   Вверх
Chingachguk
Дата 25.3.2002, 17:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1232
Регистрация: 25.3.2002
Где: Москва

Репутация: 11
Всего: 18



Урок 2. Основные понятия. Микропроцессор 8086. Решение примера Урока 1
на основе полученных знаний. Косвенная адресация: первый пример.

Итак, начнем этот урок с очень важной штуки. Введем основные определения,
которых будет немного, они будут просты... но это будут самые важные понятия
во всем этом деле !
Итак, чего вообще мы хотим ? Мы хотим научиться разговаривать с Машиной на ее
языке. Поэтому дадим понятие КОМПЬЮТЕРА(Машины), именно так, как она будет
выглядеть для Вас при программировании на ассемблере:

МАШИНА - нечто, состоящие из ПРОЦЕССОРА, ОПЕРАТИВНОЙ ПАМЯТИ и ПОРТОВ
ВВОДА-ВЫВОДА. ПРОЦЕССОР умеет выполнять ПРОГРАММЫ. Раскроем детальнее эти
понятия:

- ОПЕРАТИВНАЯ ПАМЯТЬ: набор ячеек, в котрые можно записывать числа и из которых
можно читать числа.
- ПОРТЫ ВВОДА-ВЫВОДА: набор ячеек, в котрые можно записывать числа и из которых
можно читать числа.
- ПРОЦЕССОР: функция, понимающая и реализующая числа, записанные
в ОПЕРАТИВНОЙ ПАМЯТИ как действия (КОМАНДЫ).
Выполнение команд назовем ПРОГРАММОЙ.

Итак, это важно !!! - нет никаких жестких дисков, джойстиков, мышей ... Есть только
ПРОЦЕССОР, ОПЕРАТИВНАЯ ПАМЯТЬ и ПОРТЫ ВВОДА-ВЫВОДА. Любое наше действие
будет направлено ТОЛЬКО на работу с этими тремя объектами.

Итак, мы определились: есть ОПЕРАТИВНАЯ ПАМЯТЬ, в ней храняться числа, ПРОЦЕССОР
обрабатывает эти числа и выполняет действия, заданные этими числами. Очевидно из
данных нами определений, что эти действия(КОМАНДЫ) в любом случае могут быть
направлены ТОЛЬКО на измение(чтение/запись) ОПЕРАТИВНОЙ ПАМЯТИ и
(или) ПОРТОВ ВВОДА-ВЫВОДА, либо на изменение состояния самого ПРОЦЕССОРА.

В общем виде КОМАНДУ можно представить в таком виде:

Что_Делать:<Как Делать>.

Как_Делать может быть пропущенно(<...>), ибо Что_Делать: ничего не делать
не требует дополнительных сведений. Да, есть такая команда - Ничего_Не_Делать.
Пример из жизни: команда "Лежать" также не требует дополнительных данных.

Таким образом, процессор читает ОПЕРАТИНВУЮ ПАМЯТЬ и трактует прочитанные
числа как команды. Поняв команду, он выполняет заданные в ней действия.
Команды, как уже было сказано, могут сводится к одному или нескольким
из следующих действий:

- Ничего не делать;
- Изменить что-то в ОПЕРАТИВНОЙ ПАМЯТИ;
- Изменить что-то ПОРТАХ;
- Изменить состояние процессора.

Что значит "Изменить что-то в оперативной памяти" ? Это означает изменить те числа,
которые в ней находятся: прочесть их или записать новое значение числа. То же самое
и с портами ввода-вывода.
Что означает "Изменить состояние процессора" ? Это означает повлиять на то, как он будет
трактовать(исполнять, выполнять) КОМАНДЫ.

Вернемся к второй части КОМНАДЫ - "Как Делать". Очевидно, что в ней должно содержаться
указание на область ОПЕРАТИВНОЙ ПАМЯТИ, если мы хотим ее читать/записывать, либо указание
на область ПОРТОВ, если мы хотим читать/записывать в них. Поэтому введем понятие
ЭФФЕКТИВНОГО АДРЕСА - указатель на конкретный элемент памяти, портов или процессора.

Теперь хватит теории, перейдем к  практике. Мы работали в Уроке 1 и будем работать в ближайшее
время с конкретным процессором - 8086 фирмы Intel, выпущенным еще в конце 70-х годов.
Процессор этот выполняет команды, записанные в опеределенного вида памяти, и может,
выполняя команды, изменять определенного вида порты ввода-вывода.
Память эта также есть набор ячеек, в которые можно записывать числа. Каждая ячейка
может хранить числа от 0 до 255. Порты также являются ячейками, в которые можно записывать
/из которых можно читать числа от 0 до 255.
Как храняться числа в этих ячейках ? Каждая из них состоит из 8 так называемых бит. Бит - это нечто,
могущее быть только в двух состояниях  - 0/1(Да/Нет,Триггер ... - как Вам нравиться).
Вспомним, что любое целое и неотрицательное число (0,1,2..10000...) можно разложить по степеням
двойки:

 25 = 16+8+1 = 1*2^4 + 1*2^3 + 0*2^2 + 0*2^1 + 1*2^0 = 1*16+1*8+0*4+0*2+1*1.

Итак, если мы будем трактовать 8 бит каждой такой ячейки, называемой байтом, как
коэффициенты при степени двойки, то получим возможность раскладывать числа
по 8-ми различным степеням:

2^7,2^6... 2^0.

Иначе говоря, каждое число в каждой ячейке оперативной памяти 8086 реализовано
определенным состоянием всех восьми бит этой ячейки:

Число:
         25  65  128  255
Бит0   1    1    0       1
Бит1   0    0    0       1
Бит2   0    0    0       1
Бит3   1    0    0       1
Бит4   1    0    0       1
Бит5   0    0    0       1
Бит6   0    1    0       1
Бит7   0    0    1       1.

Каждая такая ячейка называется байтом.

Итак, в 8086 записываются числа в оперативную память. Процессор может читать
эти числа, трактовать их как команды, понимать из команды, какую ячейку памяти ему
нужно изменять. Как же он это делает ? Очевидно, что ему надо знать
ЭФФЕКТИВНЫЙ АДРЕС команды, ЭФФЕКТИВНЫЙ АДРЕС ячейки, которую указано
поменять в ПАМЯТИ или ПОРТАХ. По большому счету, ЭФФЕКТИВНЫЙ АДРЕС - это номер
ячейки(номер байта) в памяти или портах. Нумерация от нуля. Например, байт(ячейка)
номер 20 содержит значение 22.
Как же процессор формирует этот ЭФФЕКТИВНЫЙ АДРЕС ? (Иными словами, где
хранится и как вычисляется номер байта) ?
Как ни странно, но он делает это весьма замысловатым образом: в процессоре имеются
так называемые РЕГИСТРЫ - это тоже ячейки "памяти" самого процессора,
но размером в СЛОВО(два байта). Можно сказать, что у Процессора есть своя небольшая
память, состоящая из набора слов. Если байт - это ячейка из восьми бит, то слово содержит
целых 16 бит, и в него можно записывать числа от 0 до 65535(посмотрите, как хранятся
числа в ячейках-байтах и поймите, какие числа можно хранить в ячейках из 16 бит). Имея
около десятка таких ячеек-слов, процессор использует некоторые из них для вычисления
ЭФФЕКТИВНОГО АДРЕСА. Вы можете подумать, что номер ячейки памяти, содержащую
текущую выполняемую команду, просто храниться в одном из РЕГИСТРОВ, а после
выполнения текущей команды в него заносится номер следующей команды:

Команда1    Байт1, Байт2,Байт3 команды 1. Номер ячейки  - 230 (Номер байта1).
Регистр_Текущей_Команды равен 230.

После выполнения команды1 процессор начнет выполнять команду2:

Команда2    Байт1, Байт2 команды 2. Номер ячейки  - 233 (Номер байта1).
Регистр_Текущей_Команды равен 233 ?

В какой-то мере у процессора 8086 это так, но в точности - не так !

Скажем вот что: процессор 8086 может работать с памятью размером
в один Мегабайт(примерно миллон ячеек по одному байту). Команды или
какие-то вспомогательные числа могут быть размещены в любой ячейке
с номером от 0 до ~1 миллиона. Т.е. номер текущей выполняемой команды
может быть в этом диапазоне. Процессор может использовать для хранения
этого номера один или несколько из своих регистров размером в слово. Вот
эти регистры, которые есть у него(все они размером в слово):

Сокращенное имя/Полное имя

IP - Instruction Pointer;
CS - Register of Code Segment;
SS - Register of Stack Segment;
SP - Stack Pointer;
ES - Register of Extra Segment;
DS - Register of Data Segment;
AX - Accumulator;
BX - Base Register;
CX - Counter
DX - Data Register;
SI - Source Register;
DI - Destination Register;
BP - Base Pointer;
FLAGS - Flags Register.

Итак, имеем этот набор регистров. Каждый размером в слово. Не обращайте
пока внимание на их названия. Прикинте, как процессор хранит номера ячеек памяти
в них.

Вы могли догадаться, что для хранения номера ячейки недостаточно любого
одного регистра из-за того, что размер памяти 8086 = 1 миллион > максимальное
число, которое можно хранит в одном слове - 65535. Два будет абсолютно достаточно,
ибо число ~один миллион легко раскладывается по степеням двойки вплоть до 20 степени,
а, значит, нам достаточно иметь всего 20 бит для его хранения ... А два регистра
обладают уже 32 битами. Например, можно придумать такую схему размещения
номера байта(ЭФФЕКТИВНОГО АДРЕСА) в двух регистрах:

1-ый регистр - 16 младших(первых) битов числа ЭФФЕКТИВНОГО АДРЕСА;
2-ой регистр - 4 старших(вторая часть) битов.

Но это не так !!! Вот что делает этот хитрый процессор: он использует действительно
два регистра, но значение одного из них он умножает на 16 и к полученному значению
прибавляет значение из другого регистра или самой команды непосредственно:

ЭФФЕКТИВНЫЙ АДРЕС = Регистр1 x 16 + Регистр 2(или непосредственное значение).

Возьмем команду из Урока 1:

 mov  byte ptr es:[320*10+10],12

Эта команда предназначена для того, чтобы записать в ячейку памяти номер
658570 числа 12. Смотрите, что в этой команде задано:

Что_Делать: Записать число в память.
Как Делать:
Число взять из самой команды - 12;
Адрес памяти вычислить, используя регистр es и непосредственное значение,
указанное в команде - 320*10+10;
Размер применика(числа в памяти для записи) - один байт.

Сейчас обратим внимание ТОЛЬКО на то, как 8086 ухитрился вычислить адрес
ячейки памяти из этой команды. Смотрите:

Регистр1 = Регистр ES(в команде так и задано)
Непосредственное значение для прибавки = 320*10+10 (тоже задано в команде)

ЭФФЕКТИВНЫЙ АДРЕС = ES x 16 + 320*10+10 = 658570.
Кто же задал значение регистра ES ??? Ясно дело, что мы ! Мы контролируем
весь процесс выполнения программы процессором ! А как мы это сделали ?
А вот как:

 mov  ax,0A000h
 mov  es,ax

Мы тут задали значение регистра ES - 0A000h = 40960.
Теперь Вы понимаете, что меняя "Что-то" в командах Урока1:

mov byte ptr es:[Что-то],Еще что-то

вы меняли Адрес Ячейки Памяти !

А вот решение задания:

 mov  byte ptr es:[320*160+110],9
 mov  byte ptr es:[320*160+111],9
 mov  byte ptr es:[320*160+112],9
 mov  byte ptr es:[320*161+110],9
 mov  byte ptr es:[320*161+111],9
 mov  byte ptr es:[320*161+112],9
 mov  byte ptr es:[320*162+110],9
 mov  byte ptr es:[320*162+111],9
 mov  byte ptr es:[320*162+112],9

- синий квадратик.

Сейчас у Вас должно возникнуть еще больше вопросов, нежели после
первого урока !!! Но и должно появиться смутное ощущение ПАМЯТИ,
которой Вы можете управлять такими вот командами.

А теперь - на закуску - Косвенная адресация !!!
Уже было сказано, как 8086 может вычислять адрес в памяти:

ЭФФЕКТИВНЫЙ АДРЕС = Регистр1 x 16 + Регистр 2(или непосредственное значение).

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

 mov  bx,320*180+100 {Заносим значение(число) 320*180+100 в регистр BX}
 mov  byte ptr es:[bx],2 {Изменим память, используя ДВА регистра для адресации}

В последней команде эффективный адрес будет вычислен так:

ЭФФЕКТИВНЫЙ АДРЕС = ES x 16 + BX.

Теперь попробуйте использовать для рисования комнады, использующие
такой способ адресации, например:

{Рисуем - три !!!}
asm
 mov  bx,320*180+100 {Заносим значение(число) 320*180+100 в регистр BX}
 mov  byte ptr es:[bx],2 {Изменим память, используя ДВА регистра для адресации}
 mov  bx,320*180+101 {Заносим значение(число) 320*180+101 в регистр BX}
 mov  byte ptr es:[bx],2 {Изменим память, используя ДВА регистра для адресации}
 mov  bx,320*180+102 {Заносим значение(число) 320*180+102 в регистр BX}
 mov  byte ptr es:[bx],2 {Изменим память, используя ДВА регистра для адресации}
end;

Если Вы выполните этот код, то должны увидеть маленькую зеленую полоску
внизу и посередине экрана.

Задание: попробуйте сделать эту полоску потолще и подлиннее, но используя
именно такие команды - mov byte ptr es:[bx]. Попытайтесь вместо таких команд
использовать уже известные Вам - типа mov  byte ptr es:[320*180+100],2.

Урок 2 закончен.  Некотрые объяснения будут даны в
уроке 3, но вопросов должно быть немеряно !!!
Да пребудет с Вами Великая Сила !


--------------------
I don't like the drugs (but the drugs like me). M.Manson.
PM MAIL ICQ   Вверх
AXEL3323
Дата 26.3.2002, 08:16 (ссылка)    |    (голосов: 0) Загрузка ... Загрузка ... Быстрая цитата Цитата


Unregistered











Привет!! Уроки - просто супер! Вот у меня вопрос :)
В пакете Tasm в отладчике td.exe для отладки существует много способов (пошаговые, бреакпоинтовский и т.д.), для краткости это F4,F7,F8, ну и F9. Так вот чтобы прервать выполнение программы надо нажать сочетание Ctrl+F2 ( Program Reset). НО в режиме отладки F9 программа не останавливается   :dg . Так надо??..Что-то я не пойму...
А отладчик версии 5.0 ( от 21.02.96), я его взял с нового диска  :D , хотя с тех пор он и не менялся....(ну я имею ввиду 16-разрядный из TASM'а)
Так как мне прервать выполнение программы?(из режима RUN) :notify
  Вверх
neutrino
Дата 26.3.2002, 12:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Gothic soul
****


Профиль
Группа: Модератор
Сообщений: 3041
Регистрация: 25.3.2002
Где: Верхняя Галилея, Кармиэль

Репутация: нет
Всего: 62



Tut mnogo, kto hochet asm uchit. Mojet Chingachguku otdelnuiu formu sdelat? S temami ... Ia bi, naprimer, zahjodil. I primeri interesnie daet. Mojet knigu vipustit "Assembler Chingachguka". Vot eto tochno ne lamievo! :satisfied


--------------------
The truth comes from within ...

Покойся с миром, Vit 
PM MAIL WWW ICQ Skype GTalk   Вверх
Chingachguk
Дата 26.3.2002, 13:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1232
Регистрация: 25.3.2002
Где: Москва

Репутация: 11
Всего: 18



Цитата

AXEL3323 Дата сообщения: 26.3.2002,08:16
Привет!! Уроки - просто супер! Вот у меня вопрос  
В пакете Tasm в отладчике td.exe для отладки существует много способов (пошаговые, бреакпоинтовский и т.д.), для краткости это F4,F7,F8, ну и F9. Так вот чтобы прервать выполнение программы надо нажать сочетание Ctrl+F2 ( Program Reset). НО в режиме отладки F9 программа не останавливается    . Так надо??..Что-то я не пойму...
А отладчик версии 5.0 ( от 21.02.96), я его взял с нового диска   , хотя с тех пор он и не менялся....(ну я имею ввиду 16-разрядный из TASM'а)
Так как мне прервать выполнение программы?(из режима RUN)


Из режима RUN можно использовать CTRL_BREAK. Но !
Если, к примеру, в программе написать замкнутный цикл:

@@Label: jmp @@Label

То нажатие этих клавиш не всегда прервет программу внутри этого кода ;) Потому, что еще выполняются прерывания ...
Отладчик может остановить работу программы двумя способами: установить свой обработчик на клавиатуру(это и есть CTRL_BREAK), но бывает код, вырубающий прерывания/маскирующий прерывания от клавиатуры, а также установить брейкпойнты (это и есть F4...).
Видимо, ты пытаешься отладить программу, которая, к примеру, где-то виснет и ты хочешь, нажав CTRL_F2, ее скинуть, узнав где она зависла ? Рекомендую действовать методом приближения к "багу": устанавливаешь брейки и постепенно доходишь до неверного кода.

Цитата

neutrino Дата сообщения: 26.3.2002,12:12
Tut mnogo, kto hochet asm uchit. Mojet Chingachguku otdelnuiu formu sdelat? S temami ... Ia bi, naprimer, zahjodil. I primeri interesnie daet. Mojet knigu vipustit "Assembler Chingachguka". Vot eto tochno ne lamievo!  


Хе, да я в жизни ничего подобного не делал, у меня даже своей странички нету ;) Хотя, может быть, дойдут руки...
К тому же я счас помогаю развивать вот этот сайт http://hi-tech.nsys.by/ - он целиком по асму.


--------------------
I don't like the drugs (but the drugs like me). M.Manson.
PM MAIL ICQ   Вверх
neutrino
Дата 26.3.2002, 15:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Gothic soul
****


Профиль
Группа: Модератор
Сообщений: 3041
Регистрация: 25.3.2002
Где: Верхняя Галилея, Кармиэль

Репутация: нет
Всего: 62



Da, sait nichego, osobenno fanariki na solnechnih batareikah ponravilis. No dolgo gruzitsia.  :satisfied


--------------------
The truth comes from within ...

Покойся с миром, Vit 
PM MAIL WWW ICQ Skype GTalk   Вверх
Chingachguk
Дата 26.3.2002, 22:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1232
Регистрация: 25.3.2002
Где: Москва

Репутация: 11
Всего: 18



Урок 3. Продолжаем работать с памятью. Первый цикл. Изучение
двухкомпонетного адреса.

Упс, как говорит Б.Спирс, ай дид ит эгейн. Ну и мы тоже эгейн. В смысле, снова
поработаем с памятью.
Итак, память. Памяти у нас примерно миллион ячеек по 1 байту. Где-то находятся
байты нашей программы, которую процессор сейчас читает байт за байтом и выполняет,
где-то байты программ БИОС-а, где-то - ДОС-а. Ну а начиная с байта нумер 655360
находится так называемый видеобуфер. Можно сказать по-другому - с номера A0000h.
Это - шестнадцетеричная система исчисления. Эти числа равны: 655360=A0000h, просто они
записаны по-разному. Здесь мы не будем подробно разбирать эту систему, приведем только
пример преобразования числа A0000h в "нормальный" вид:

A0000h = A*16^4+0*16^3+0*16^2+0*16^1+0*16^0 = 10*16^4 = 655360.

h - просто обозначение такой системы исчисления;
A = 10, B = 11, C = 12, D = 13, E = 14, F = 15 - поскольку основанием является 16, то для записи
числа НЕ ХВАТАЕТ чисел "привычной" десятичной системы - 0,1,2,3..9.
Вы вполне можете обойтись виндовым или любым другим калькулятором для
такого рода преобразований.
Ага, так что же такое видеобуфер ? Он же - видеопамять, видеокарта, ... Для
нас нет никаких железок, джемперов, жестких дисков, повторяю !
Есть только память, порты и процессор. Видеобуфер для нас в данном
случае - просто КУСОК ПАМЯТИ. Начинается с байта номер A0000h. Почему же мы
выделяем этот кусок особо ? А вот почему: помните, у нас в Уроке 1 был такой код:

 {Устанавливаем графический режим монитора 13h, 320x200, 256 цветов}
 asm
 mov  ax,0013h
 int  10h
 end;

Всего две команды, а делают сколько ! После их выполнения БИОС сделает так, что
всякая запись чисел в этот видеобуфер приведет к изменениям на мониторе !
Как это происходит ? С нашей стороны "забора" мы пишем в ячейки этого куска памяти
числа. Они там и остаются, пока их не изменить. С другой стороны "забора" сидит
аппаратура, "железо", как ее еще называют, которая СОВЕРШЕННО НЕЗАВИСИМО от
выполнения наших программ начинает трактовать эти числа КАК ЦВЕТА ТОЧЕК монитора.
Это ее БИОС так заставил делать. Переключил в такой режим. Бывают и другие режимы
работы видеокарты-видеоаппаратуры - текстовые там, графические ... Мы в графическом.
Но это все нам неважно. Важно нам только то, как надо писать в эту память числа, чтобы
аппаратура эта нарисовала на их основе изображение на мониторе.
Более детально. Вспомним, что режим у нас - 320x200, 256 цветов. 320 точек по
горизонтали, 200 - по вертикали. Каждая точка может иметь 256 различных цветов.
1 байт памяти как раз может иметь 256 различных состояний. Число в байте номер
A0000h аппаратура трактует как цвет верхнего левого пикселя, число в следующем
байте - как цвет следующего(двигаясь направо) пикселя и так далее. На одну строчку
320 пикселей - значит, и в памяти 320 байт. 321 байт начиная с байта A0000h - это уже
самый левый пиксель второй стороки и так далее:

Номер пикселя по
горизонтали/вертикали - номер байта в памяти
       0             1                2              3
0  A0000h  A0000h+1 A0000h+2 A0000h+3 ...
1  A0000h+320...
2
...

Ага. Нетрудно сообразить, что для всех 320x200 точек монитора требуется
320x200 = 64000 байт памяти. Например, запись в байт с номером
A0000h+320x200-1 приведет к изменению цвета нижнего правого пикселя.
Проверим это. Нарисуем вертикальную горизонтальную линию на мониторе,
желтого цвета, по самой первой строке от левого до правого края монитора.
От уха до уха, так сказать. Для этого мы должны записать
число 14(желтый цвет) в байты с номерами
A0000h,A0000h+1... A0000h+319 - всего 320 последовательных байт.
Вспоминаем, как процессор может делать это:

 mov  ax,0A000h {Заносим в регистр AX число 0A000h}
 mov  es,ax {Копируем число из регистра AX в регистр ES, фактически - 0A000h}
 mov  byte ptr es:[0],14 {Записываем по адресу 0A000hx16+0 байт значением 14}
 mov  byte ptr es:[1],14 {Записываем по адресу 0A000hx16+1 байт значением 14}
 mov  byte ptr es:[2],14 {Записываем по адресу 0A000hx16+2 байт значением 14}
 ...

Не надоело ? Верно, надо делать цикл. Как и в других языках программирования,
в асме тоже есть циклы. Что же за цикл нам нужен ? Цикл из 320 повторений,
в цикле должен вертеться индекс, позволяющий нам записывать СМЕЩЕНИЕ
адреса в команде от 0 до 319. СМЕЩЕНИЕ - это та часть эффективного адреса,
который процессор вычисляет из команды и добавит его к СЕГМЕНТНОМУ
регистру, умноженному на 16:

 mov  byte ptr es:[1],14
 Эффективный адрес =             es * 16           +         1
                                        СЕГМЕНТНАЯ ЧАСТЬ    СМЕЩЕНИЕ.

В этой команде смещение указано явно. Жестко. Сколько бы раз мы не выполнили
эту команду, она запишет байт 14 в одну и ту же ячейку памяти. Если только не
менять значение сегментного регистра es. Почему бы нам не поменять его ?
А вот, например, почему: нетрудно заметить, что ЛЮБОЕ значение в сегментном
регистре es при смещении = 1 нам НИКОГДА не позволит писать в ячеку памяти
номер A0000h(подумайте, почему !;). Теперь вспомним, что в Уроке 2 мы проходили
так называемую КОСВЕННУЮ адресацию:

 mov bx,1
 mov byte ptr es:[bx],14 {Записываем по адресу 0A000hx16+bx байт значением 14}.

Процессор использовал для получения смещения регистр ! А регистры мы можем
менять ! Тогда начнем писать цикл:

 mov  ax,0A000h {Заносим в регистр AX число 0A000h}
 mov  es,ax {Копируем число из регистра AX в регистр ES, фактически - 0A000h}
 mov bx,0 {Смещение первой точки равно 0}
 mov byte ptr es:[bx],14
 ADD bx,1 {Добавить к регистру BX 1 !}

Вот, новая команда(ADD) ! До сих пор мы работали с одной командой засылки
значения - mov(от move, англ.). А команда "ADD" (addition, сложить) позволяет
добавлять к приемнику операции (здесь - регистр BX) значение источника - "1".
И регистр BX станет равен 1 !
Что же дальше ? Последуем классическому типу циклов:

repeat  
{Тело цикла}
Until {Условие=TRUE}

Очевидно, что телом цикла у нас выступает команда
закраски - mov byte ptr es:[bx],14. Командой add bx,1 мы изменили регистр BX
и можем анализировать его состояние (Условие=TRUE). Что же мы будем
анализировать ? Если мы хотим задать смещение от 0 до 319, то нам годятся
все значения bx в этом диапазоне, иначе цикл надо прерывать. Делаем это:

add bx,1 {inc(BX) или BX:=BX+1 или BX++}
CMP bx,319 {Сравнить BX и 319}
JBE МЕТКА_НАЧАЛА_ЦИКЛА - @repeat.

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

CMP bx,319 {COMPARE BX WITH 319}
JBE @repeat {JUMP IF BELOW OR EQUAL}

Вы видите расшифровку сокращений этих команд. CMP-это сравнение.
BX с 319. По результатам этого сравнения мы можем писать команды
переходов. А фактически - приказать процессору перейти на конкретную
команду, да еще и в зависимости от результата сравнения - JBE.
А вот как выглядит весь код:

begin
 {Устанавливаем графический режим монитора 13h, 320x200, 256 цветов}
 asm
 mov  ax,0013h
 int  10h
 end;
 asm
 {Кусок рисования}
 mov ax,0A000h
 mov es,ax
 mov bx,0
@Repeat:
 mov byte ptr es:[bx],14
 add bx,1
 cmp bx,319
 jbe @Repeat
 {Кусок рисования - Закончен}
 end;
 {Ожидаем нажатия клавиши}
 asm
 mov  ah,0
 int  16h
 end;
 {Устанавливаем текстовый режим монитора 03h, 80x25, 16 цветов текста и фона}
 asm
 mov  ax,0003h
 int  10h
 end;
end.

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

Выполните этот код. Убедитесь в наличии желтой полосы вверху экрана.

Метка начала цикла у нас называется @Repeat. Почему вначале @ ?
Это особенность asm-вставок языка Паскаль. В настоящем ассемблере
Вы можете извращаться так, как вам хочется, хотя это ограничение не слишком
сильное. Вы могли назвать метку @MY_LABEL. Важно одно: Вы сравнили командой
CMP регистр BX с 319, и, если его значение МЕНЬШЕ(BELOW) или(OR)
равно(EQUAL) 319, то передаете управление на эту метку.

Примечание: Вам должно быть непонятно, ОТКУДА команда JBE знает про
результаты выполнения команды сравнения (CMP).

Усложним слегка пример. Хочу, чтобы мы нарисовали желтую полосу не по
первой сверху строке, а по строке номер 160 ! Думаю, Вам понятно, где
начинаются байты, отвечающие этой строке:

Номер пикселя по
горизонтали/вертикали - номер байта в памяти
           0                                     1                               2
160  A0000h+160*320  A0000h+160*320+1 A0000h+160*320+2...

А это означает, что начальное смещение в цикле надо задать просто
не с нуля, а с 160*320:

 {Кусок рисования}
 mov ax,0A000h
 mov es,ax
 mov bx,160*320 {Начальное смещение !}
@Repeat:
 mov byte ptr es:[bx],14
 add bx,1
 cmp bx,160*320+319 {Внимание ! Мы изменили и эту команду !}
 jbe @Repeat
 {Кусок рисования - Закончен}

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

Важный момент:

 cmp bx,160*320+319 {Внимание ! Мы изменили и эту команду !}

У нас регистр BX уже меняется не от нуля ! И закончим мы рисовать не тогда,
когда он станет 320, а когда 160*320+320 !

А теперь еще навороченне !!! Мы можем задавать эффективный адрес, варьируя
две компоненты: сегмент и смещение. Только что мы сместили полосу на экране,
меняя смещение. Это было естественно, поскольку мы занесли в регистр es такое
число, что процессор, умножая его на 16, как раз втыкался в начало видеобуфера:

es * 16 = 0A000h * 16 = 0A0000h !

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

Номер пикселя по
горизонтали/вертикали - номер байта в памяти
           0                                     1                               2
160  A0000h+160*320  A0000h+160*320+1 A0000h+160*320+2...

A0000h бралось ранее из es. Смещения - 160*320+0,1,2.. - из bx.
А можно ли задать так значение es, чтобы смещение, к примеру,
начиналось с 0 ? Вот так:

          0       1     2
160  X+0h  X+1 X+2... - ?

Здесь X - это неизвестное. Оно должно быть получено процессором так:

X = es*16

А ячейки памяти должны иметь одинаковые адреса:

X+0h = A0000h+160*320.

Решая это несложное уравнение, найдем, что X = AC800h = 706560.
Значит, es = AC800h / 16 = AC80h ! И измененный код готов:

 {Кусок рисования}
 mov ax,0AC80h
 mov es,ax
 mov bx,0 {Начальное смещение ! - опять нуль !}
@Repeat:
 mov byte ptr es:[bx],14
 add bx,1
 cmp bx,319 {Внимание ! Мы изменили и эту команду ! - вернули !}
 jbe @Repeat
 {Кусок рисования - Закончен}

Заделаем этот пример понагляднее ! Сначала нарисуем желтую полосу
в строке 160 "обычным" способом - занося перед циклом в регистр es число
0A000h, а потом нарисуем поверх желтой полосы фиолетовую, но уже занося
в es значение 0AC80h ! Вот кодец:

 {Кусок рисования}
 mov ax,0A000h
 mov es,ax
 mov bx,160*320 {Начальное смещение !}
@RepeatYellow:
 mov byte ptr es:[bx],14
 add bx,1
 cmp bx,160*320+319
 jbe @RepeatYellow
 {Остановим программу известным нам способом}
 mov  ah,0
 int  16h
 {Рисуем, но уже другим способом !}
 mov ax,0AC80h
 mov es,ax
 mov bx,0 {Начальное смещение ! - опять нуль !}
@RepeatMagneta:
 mov byte ptr es:[bx],13 {Цвет не желтый !}
 add bx,1
 cmp bx,319
 jbe @RepeatMagneta
 {Кусок рисования - Закончен}

Проверьте этот код !

Ну вот. А теперь я хочу, чтобы Вы выполнили два небольших заданьица:

1) Заполнить ВЕСЬ экран каким-нибудь цветом. Желательно - красным.
2) Нарисовать горизонтальную полосу зеленого цвета в 64 строке экрана:
    - занеся в регистр es адрес начала видеобуфера;
    - занеся в регистр es такое значение, чтобы рисовалась та же полоса в
      64 строке экрана, Но вот смещение Вы бы задавали с нуля !

Не возбраняется, а приветствуется появление Ваших решений до выкладки
Урока 4, где они будут приведены ! Будет неплохо поглядеть на Ваш код
и сделать обсуждам !

Урок 3 закончен.
Да пребудет с Вами Великая Сила !


--------------------
I don't like the drugs (but the drugs like me). M.Manson.
PM MAIL ICQ   Вверх
Melancholy
Дата 8.4.2002, 12:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 43
Регистрация: 1.4.2002

Репутация: нет
Всего: нет



прога заполняет весь экран красным цветом.


begin
{Устанавливаем графический режим монитора 13h, 320x200, 256 цветов}
asm
mov  ax, 00013h
int  010h
end;
asm
{Кусок рисования}
mov  ax, 0A000h
mov  es, ax
xor  di, di {обнуляем регистр di}
mov  al, 004h
mov  cx, 64000 {счетчик = 64000  =  320 * 200}
rep  stosb {выполняем 64000 раз команду stosb}
         {stosb - помещает значение регистра al в ячейку памяти es:di}
{Кусок рисования - Закончен}
end;
{Ожидаем нажатия клавиши}
asm
mov  ah,0
int  16h
end;
{Устанавливаем текстовый режим монитора 03h, 80x25, 16 цветов текста и фона}
asm
mov  ax,0003h
int  10h
end;
end.

а как тебе такой код?
PM MAIL ICQ   Вверх
Chingachguk
Дата 8.4.2002, 15:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1232
Регистрация: 25.3.2002
Где: Москва

Репутация: 11
Всего: 18



Цитата

Melancholy Дата сообщения: 08.4.2002,13:24
прога заполняет весь экран красным цветом.

{Кусок рисования}
mov  ax, 0A000h
mov  es, ax
xor  di, di {обнуляем регистр di}
mov  al, 004h
mov  cx, 64000 {счетчик = 64000  =  320 * 200}
rep  stosb {выполняем 64000 раз команду stosb}
{stosb - помещает значение регистра al в ячейку памяти es:di}
{Кусок рисования - Закончен}


Неплохо ! ж)
Видимо, ты знаешь ассемблер на каком-то уровне !
Всего одна ошибка: пропустил команду "cld" ;)
Но код почти на 100% работает !

Правда, в уроке подразумевалось более "незамысловатое" решение.

А как насчет второго задания ? :)


--------------------
I don't like the drugs (but the drugs like me). M.Manson.
PM MAIL ICQ   Вверх
Melancholy
Дата 8.4.2002, 15:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 43
Регистрация: 1.4.2002

Репутация: нет
Всего: нет



Вариант 1
begin
{Устанавливаем графический режим монитора 13h, 320x200, 256 цветов}
asm
mov  ax, 00013h
int  010h
end;
asm
{Кусок рисования}
mov  ax, 0A000h
mov  es, ax
mov  di, 320*64
mov  al, 004h
mov  cx, 320
cld {между прочим вероятность, что флажек CF установлен очень мола!!!}
rep  stosb {выполняем 64000 раз команду stosb}
{Кусок рисования - Закончен}
end;
{Ожидаем нажатия клавиши}
asm
mov  ah,0
int  16h
end;
{Устанавливаем текстовый режим монитора 03h, 80x25, 16 цветов текста и фона}
asm
mov  ax,0003h
int  10h
end;
end.
Вариант 2
begin
{Устанавливаем графический режим монитора 13h, 320x200, 256 цветов}
asm
mov  ax, 00013h
int  010h
end;
asm
{Кусок рисования}
mov  ax, 0A000h + 20*64
mov  es, ax
xor  di, di
mov  al, 004h
mov  cx, 320
cld
rep  stosb {выполняем 64000 раз команду stosb}
{Кусок рисования - Закончен}
end;
{Ожидаем нажатия клавиши}
asm
mov  ah,0
int  16h
end;
{Устанавливаем текстовый режим монитора 03h, 80x25, 16 цветов текста и фона}
asm
mov  ax,0003h
int  10h
end;
end.

P.S. Что ты имеешь введу "почти на 100% работает"?
PM MAIL ICQ   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Asm для начинающих"
MAKCim
  • Проставьте несколько ключевых слов темы, чтобы её можно было легче найти.
  • Не забывайте пользоваться кнопкой КОД.
  • Телепатов на форуме нет! Задавайте чёткий, конкретный и полный вопрос. Указывайте полностью ошибки компилятора и компоновщика.
  • Новое сообщение должно иметь прямое отношение к разделу форума. Флуд, флейм, оффтопик запрещены.
  • Категорически запрещается обсуждение вареза, "кряков", взлома программ и т.д.

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, MAKCim.

 
 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Asm для начинающих | Следующая тема »


 




[ Время генерации скрипта: 0.1806 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.