|
27.03.2005, 17:38
|
#1
|
Земляк
Регистрация: 24.12.2003
Адрес: Уже не из Мегиона
Сообщений: 785
Галерея:
0
Р:
|
Контрольная на ASM. В самомодифицирующихся кодах ....
Разгребал свои старые кунстюшки и набрёл на контрольную
по программированию на ассемблере. Помню - чтоо препод попался противный - фамилие его - как cейчас помню - Мирошниченко, эдакий
из не служивших в армии или на флот, но с апломбом и понтами и понтаааами .... Сейчас уже кандидаддддддд каких-то там наук ... Честно предложил ему - мужик - я знаю ассемблер, проекты на нём писал, давай сядем, побеседуем, ну ты мне 5 баллов поставишь и разойдёмся - как в море корабли ....
УУУУУУУУУУУУ ! Как оне развыступались ... Как оне слова наговорили ...
Ах ты - думаю - говнюк ... Будет тебе контрольная. Ну и - наделал. Как корова лепёшку - много, красиво и главное - полезно для природы и придраться не к чему ...
Оне глянули, поскучнели, задали пару вопросов и - поставили 5 баллов. Заслуженно торчит в дипломе .... Желающие типа глянуть - могут поглянуть ....:
Код:
;
; КУРСОВАЯ РАБОТА ПО ДИСЦИПЛИНЕ "ТЕХНОЛОГИЯ ПРОГРАММИРОВАНИЯ"
;
; Тема курсовой работы получена из методического
; указания "Технология программирования" , Томск 1998 г.
; Страница 29 , задание 2.4
;
; "Исследование расширеных функций DOS для обработки текстовых файлов"
;
; Задание :
; Создать в текстовом редакторе файл вида :
;
; ???????????????????????????????????????????????
; ?Факультет ? Номер ? Кафедра ? Корпус ?
; ? ? Специальности ? ? ?
; ???????????????????????????????????????????????
; ? АВТФ ? 3 ? ВТ ? 10 ?
; ? АВТФ ? 4 ? АиКС ? 10 ?
; ? АВТФ ? 3 ? АП ? 5 ?
; ? АВТФ ? 4 ? РТС ? 10 ?
; ? АВТФ ? 2 ? ОСУ ? 5 ?
; ? ЭФФ ? 1 ? ИИТ ? 10 ?
; ? ЭФФ ? 2 ? РТ ? 4 ?
; ? ЭФФ ? 1 ? СТУ ? 4 ?
; ???????????????????????????????????????????????
;
; Написать программу, с помощью которой создать новый файл,
; включив в него только строки старого файла содержащие
; данные " в 10 корпусе с номером специальности > 2 ".
;
;---------------------------------------------------------------------
;
; Решение:
;
; В качестве ассемблера используем TASM v3.02i .
; В качестве компановщика используем Tlink v4.1 . Столь старые
; версии продукта были взяты из первых попавшихся под руку . ;-}
;
; Для массива данных статически выделим заранее приготовленный
; объем инициализированных данных в 1K.
;
; Оформим программу в виде полноценного EXE-файла .
;
; Только ради возможности воспользоваться инструкциями PUSHA/POPA
; поставим прагму компилятора .286c ( использование инструкций
; процессора Intel 80286 в реальном режиме работы процессора ).
;
;
.286c
;
; Описываем сегмент стека
; -----------------------------------------------
;
sseg segment para stack 'Stack'
dw 4096 dup (?) ; Стек у нас - величина пословная ...
sseg ends
;
; Описываем сегмент данных
; -----------------------------------------------
;
dseg segment para 'Data'
for_file db 1024 dup (0) ; сюда считываем исходный файл
filein db 'FILEIN.TXT',0 ; имя исходного файла
fileout db 'FILEOUT.TXT',0 ; имя результирующего файла
fullfilein db 64 dup (0) ; полное имя - с путем - исходного файла
fullfileout db 64 dup (0) ; полное имя - с путем - результирующего файла.
handlein dw 0h ; переменная для записи указателя исходного
; файла
handleout dw 0h ; переменная для записи указателя файла
; результата
filelength dw 0 ; длина исходного файла с данными
end_wr db '???????????????????????????????????????????????',0Dh,0Ah
error_0 db 0Ah,0Dh,0Ah,0Dh
db 'Ошибка открытия файла с исходными данными',0Ah,0Dh,'$'
error_01 db 0Ah,0Dh,0Ah,0Dh
db 'Ошибка определения размера файла с исходными данными',0Ah,0Dh,'$'
error_02 db 0Ah,0Dh,0Ah,0Dh
db 'Исходный файл должен быть размером не более 1К',0Ah,0Dh,'$'
error_03 db 0Ah,0Dh,0Ah,0Dh
db 'Ошибка при чтении исходного файла',0Ah,0Dh,'$'
error_04 db 0Ah,0Dh,0Ah,0Dh
db 'Ошибка при создании файла результата',0Ah,0Dh,'$'
error_05 db 0Ah,0Dh,0Ah,0Dh
db 'Ошибка записи в файл результата',0Ah,0Dh,'$'
dseg ends
cseg segment para 'Code'
begin proc far
assume cs:cseg; ss:sseg ; ds:dseg ; es:dseg ; DS=ES !
;
; Инициализируем сегментные регистры DS/ES .
; Стек инициализируется автоматически при запуске программы .
;
xor ax,ax
mov ax,dseg
mov ds,ax
mov es,ax
; Принимаем по умолчанию , что файл с данными находится
; в том же каталоге , что и исполняемая программа
; Получаем информацию об этом самом каталоге - 'где я есть ?'
; Дабы не иметь в дальнейшем проблем с инициализацией файлов
; данных , ОБЯЗАТЕЛЬНО помещаем их в том же каталоге , что и
; основную программу . Для этого через PSP и Enviroment запускаемого
; файла находим полный путь к нему , разбираем его на составные
; части и создаем заново полный путь к файлам данных .
;
; Часть нижеследующих фишек можно было-бы получить по-умолчанию ,
; спрятав например ES в стек ДО иницилизации сегмента .
;
mov ah,62h
int 21h ; Получили в bx адрес сегмента PSP , старый
; ES прятать не будем , поскольку DS=ES , всегда
; восстановим
;
mov es,bx ; установили ES на него
mov ax,es:2Ch ; получили адрес СЕГМЕНТА начала массива строки окружения.
mov es,ax ; поставили его в ES .
;
; Ищем окончание массива окружения. Признак - слово , состоящее из двух
; нулевых байт . Его адрес+1 - адрес строки с именем исполняемого файла.
;
xor bx,bx
;
; Адрес начала enviroment = ES:0
;
search: inc bx ; Enviroment в ЛЮБОМ СЛУЧАЕ не будет 0-вого размера,
; поэтому для удобства программирования начнем
; его со второго символа
mov al,es:[bx] ; mov byte ptr
cmp al,0h ; байт нулевой ?
jne search ; нет , тогда - увеличили адрес смещения на 1
cmp al,es:[bx+1] ; а следующий за ним байт - тоже нулевой ??
jne search ; нет , это окончание очередной строки enviroment
;
add bx,04h ; Да - второй байт нулевой . ОК . Получаем
; адрес строки , в которой в ASCIIZ записан
; полный путь , с которым запустился наш исполняемый
; файл . ( +1 - недостающий INC , +3 служебных байта )
;
mov ax,es
mov dx,bx
;
; "Откусим" от строки имя файла .
;
push bx ; прячем в стек адрес начала строки - всплывет
; он в ax на метке end_kus
; ищем адрес конца строки .
kus0: mov ah,es:[bx] ; помещаем в ah очередной символ
cmp ah,0h ; это NULL ?
je end_string ; да - пошли 'кусать'
inc bx ; нет
jmp short kus0 ; увеличиваем смещение на 1 и обратно
end_string:
;
; Здесь в bx должен лежать адрес конца строки . ES:[BX]
; Необходимо убрать имя файла запускаемой программы ,
; чтобы только полный путь к ее каталогу .
;
kus1: mov ah,es:[bx]
cmp ah,'\' ; это ПЕРВЫЙ символ-разделитель с конца строки ?
je end_kus ;Да. Пошли делать полное имя файлов для чтения и записи
dec bx
jmp short kus1
end_kus: pop ax ; в ES:AX у нас сейчас адрес начала строки, содержащей
; полный путь к директории , откуда запущен исходный
; файл , в ES:BX - адрес конца строки .
mov cx,bx
sub cx,ax ; длина этой самой строки-1 байт - теперь в cx
inc cx ; перешлем строку командой movsb
push es ;
push ds ; Поменяем адреса сегментов для
pop es ; подобной операции
pop ds ;
push cx
push ax
cld
mov si,ax ; адрес НАЧАЛА строки , которую пересылаем
lea di,es:fullfilein
rep movsb
pop ax
pop cx
push cx ; еще раз сохраняем cx
push cx ; для операций с дополнением конца имени файлов
; источника и приемника данных
cld
mov si,ax ; адрес НАЧАЛА строки , которую пересылаем
lea di,es:fullfileout
rep movsb
; В результате - в fullfilein/out лежит полный путь к файлам
; данных без имени самого файла .
push es
pop ds ; сегментные адреса регистров ES/DS снова равны
;
; Узнаем длину имени файла-источника
;
xor bx,bx
lea si,filein ; становимся на начало строки с коротким именем файла
so0: mov al,ds:si[bx]
cmp al,0h
je addpath
inc bx
jmp short so0
;
; Создаем полное имя к файлу источнику
;
addpath: pop cx ; ПЕРВЫЙ тот самый cx с длиной строки пути к файлу
lea si,filein
lea di,fullfilein
add di,cx ; добавляем в конец того самого пути fullfilein
;
mov cx,bx
cld
rep movsb
;
; Узнаем длину имени файла-приемника
;
xor bx,bx
lea si,fileout ; становимся на начало строки с коротким именем файла
so1: mov al,ds:si[bx]
cmp al,0h
je addpath1
inc bx
jmp short so1
;
; Создаем полное имя к файлу-приемнику
;
addpath1: pop cx ; ВТОРОЙ тот самый cx с длиной строки пути к файлу
lea si,fileout
lea di,fullfileout
add di,cx ; добавляем в конец того самого пути
mov cx,bx
cld
rep movsb
; Все . В строке fullfilein у нас лежит путь для открытия
; файла для чтения данных , в fullfileout - путь для открытия
; файла , который мы создадим для записи данных
; Примем по умолчанию , что файлы данных лежат именно в той директории,
; что и исходные файлы . Откуда-бы не запускалась сама программа
mov ax,3D00h ; открываем файл только на чтение
lea dx,fullfilein
int 21h
jnc ok0
mov ax,0900h
mov dx,offset error_0
int 21h
jmp end_programm
ok0: mov ds:handlein,ax
;
; Определяем размер файла
mov ax,4202h ; перемещаем указатель на конец файла
mov bx,ds:handlein
xor cx,cx ; никаких смещений относительно
xor dx,dx ; конца файла нам дополнительно НЕ надо
int 21h
jnc ok1
err1: mov ax,0900h
mov dx,offset error_01
int 21h
jmp end_programm
ok1: cmp dx,0h ; файл очень большого размера ?
je ok2 ; нет
err2: mov ax,0900h
mov dx,offset error_02
int 21h
jmp end_programm
ok2: cmp ax,400h ; файл больше 1K ?
jbe ok3
jmp short err2
; и так - в ax у нас - размер файла
ok3: push ax ; выплывет в cx на метке ok4:
mov ds:filelength,ax
; переместим указатель файла снова на начало
mov ax,4200h ; перемещаем указатель на начало файла
mov bx,ds:handlein
xor cx,cx ; никаких смещений относительно
xor dx,dx ; конца файла нам дополнительно НЕ надо
int 21h
jnc ok4
jmp short err1
ok4: ;
; читаем наконец-то данные из файла ;-}}
;
pop cx ; сюда - сколько читаем байт
mov bx,ds:handlein
mov ah,3Fh
lea dx,ds:for_file ; грузим здесь исходный файл в память
int 21h
jnc ok5
mov ax,0900h
mov dx,offset error_03
int 21h
jmp end_programm
ok5:
; Данные прочитались и находятся сейчас в массиве ,
; начинающемся с метки for_file . Поскольку требованием
; курсового является отправить в выходной файл только
; данные о "10 корпусе" с номером специальности БОЛЬШЕ 2 ,
; то есть фактически вывести строки , содержащие только
; цифры , отвечающие этим двум условиям , то попросту
; просканируем исходный массив данных на соответствие
; требованиям задачи .
;
; Для начала - откроем выходной файл и сбросим
; в него заголовки таблицы
mov ah,3Ch ; создать файл
xor cx,cx ; с нормальными атрибутами
lea dx,ds:fullfileout
int 21h
jnc new0
mov ax,0900h
mov dx,offset error_04
int 21h
jmp end_programm
new0: mov cx,0C4h ; померял ручками - сбрасываем только
; заголовок таблицы из исходного файла
mov bx,ax ; в результирующий
mov ds:handleout,bx ; поместили в переменную handleout указатель
; на oufile
lea dx,ds:for_file
mov ah,40h
int 21h
jnc new1
newerr0: mov ax,0900h
mov dx,offset error_05
int 21h
jmp short end_programm
;
; здесь начали сканирование данных
; для поиска информации
;
new1: xor bx,bx ; установили указатель на начало .
lea si,for_file ; загрузили адрес массива для сканирования
scan0: mov ax,'01' ; из-за организации памяти в PC
; (старший байт соответствует старшему адресу)
; меняем условия ПОСЛОВНОЙ проверки ( на самом
; деле там конечно же ASCII-10
cmp bx,ds:filelength ; случаем , весь массив не просканировали ?
jae end_write ; да . Тогда - дописываем линейку в конец
; файла и закрываем его .
cmp word ptr ax,ds:[si+bx] ; Это цифра '10' ??
je scan1 ; да . Ушли проверять строку на второе условие
inc bx
jmp short scan0
scan1:
push bx ; в bx лежит адрес слова , содержащего
; цифру 10 . Вылезет он только на метке any
; Теперь опрашиваем строку
mov dh,'9' ;
mov dl,'0' ;
scan2: dec bx ; в обратном направлении - на предмет
mov ah,ds:[si+bx] ; нахождения номера специальности .
cmp ah,dl ; какая в нем цифра ? меньше 0-вого номера
jb scan2 ; специальности в задании нет, больше 9-го
cmp ah,dh ; тоже нет .
ja scan2
; нашли цифирь с номером специальности
cmp ah,'2' ; это ASCII от 0 и до 9 ( 32h,33h,34h & etc. )
jb any ; номер специальности меньше 2 ??
scan3: dec bx ; нет - больше !
cmp byte ptr ds:[si+bx],0Ah ; ищем начало строки с "корпус 10" ....
jne scan3 ; и Номер Специальности > 2
inc bx ; чтобы уйти с 0D и встать на ее начало .
push bx ; запоминаем адрес ее начала
scan4: inc bx
cmp byte ptr ds:[si+bx],0Dh ; ищем конец строки с "корпус 10" ....
jne scan4
; получили адрес конца строки с "корпус 10" ...
; пишем строку в файл
mov cx,bx ; в cx теперь адрес конца очередной строки для записи
pop bx ; в bx - ее начало
mov dx,bx ; в dx теперь - ее начало
sub cx,bx ; в сx теперь - ее длина
inc cx ; чтобы записалось еще и 0Ah,0Dh
inc cx ;
mov bx,ds:handleout ; в bx - указатель на выходной файл
mov ah,40h
int 21h
jnc any ; если все OK - то пошли на продолжение сканирования .
jmp short newerr0 ; если нет - то на сообщение об ошибке .
any: pop bx ; достали адрес , по которому мы нашли '10'
inc bx ; +2 к нему - чтобы пропустить полностью '10'
inc bx
jmp scan0 ; и поехали искать следующее 10
end_write:
mov bx,ds:handleout ; в bx - указатель на выходной файл
lea dx,end_wr ; добавим в конец выходного файла ;
mov cx,31h ;
mov ah,40h
int 21h
jnc end0 ; если все OK - то пошли на закрытие файла
jmp newerr0 ; если нет - то на сообщение об ошибке .
end0: mov ah,3eh
mov bx,ds:handleout
int 21h
mov ah,3eh
mov bx,ds:handlein
int 21h
end_programm:
mov ax,4c00h
int 21h
begin endp
cseg ends
end begin
__________________
-----------------
С уважением:
Игорь
|
|
|
28.03.2005, 00:22
|
#2
|
Почетный ветеран
Регистрация: 05.08.2003
Адрес: N61°3'E76°6' - Мегион
Сообщений: 5,498
Р:
|
Контрольная на ASM. В самомодифицирующихся кодах ....
2 Игорь
Это я подправил - [code ] поставил, читается лучше...
|
|
|
28.03.2005, 09:58
|
#3
|
Земляк
Регистрация: 24.12.2003
Адрес: Уже не из Мегиона
Сообщений: 785
Галерея:
0
Р:
|
Контрольная на ASM. В самомодифицирующихся кодах ....
Цитата:
Сообщение от Kosting
2 Игорь
Это я подправил - [code ] поставил, читается лучше...
|
Согласен, но пргрмму писал в состоянии сильного изменения
сознания на коленке и за адын вечер, чтобы утром отдать
преподу ( хотелось сказать - бррросить в его гадскую морду ) ... ;-)
P.S. Вообще - куча всяких контрольных от ASM'а осталась - кому
из Томских политехников надо-ть - пишите - отдам нафих ...
Могу и тулзы всякие по мелочам ...
__________________
-----------------
С уважением:
Игорь
|
|
|
09.04.2007, 22:49
|
#4
|
Гайка
Регистрация: 20.08.2003
Сообщений: 9,650
|
Контрольная на ASM. В самомодифицирующихся кодах ....
можешь на почту кинуть контрольные свои?
__________________
«Ведь я только всего и хочу, чтобы все всегда было по-моему» Б.Шоу
|
|
|
10.04.2007, 08:51
|
#5
|
Земляк
Регистрация: 24.12.2003
Адрес: Уже не из Мегиона
Сообщений: 785
Галерея:
0
Р:
|
Re: Контрольная на ASM. В самомодифицирующихся кодах ....
Цитата:
Сообщение от Gaido
можешь на почту кинуть контрольные свои?
|
Аддрессс !!!
В ICQ постучался - а тишинаааа ...
__________________
-----------------
С уважением:
Игорь
|
|
|
11.04.2007, 01:14
|
#6
|
Гайка
Регистрация: 20.08.2003
Сообщений: 9,650
|
Контрольная на ASM. В самомодифицирующихся кодах ....
ответила в аську. Заранее спасибо
__________________
«Ведь я только всего и хочу, чтобы все всегда было по-моему» Б.Шоу
|
|
|
11.04.2007, 09:18
|
#7
|
Земляк
Регистрация: 24.12.2003
Адрес: Уже не из Мегиона
Сообщений: 785
Галерея:
0
Р:
|
Re: Контрольная на ASM. В самомодифицирующихся кодах ....
Цитата:
Сообщение от Gaido
ответила в аську. Заранее спасибо
|
Выслал всё что было со старых времён ...
__________________
-----------------
С уважением:
Игорь
|
|
|
Здесь присутствуют: 1 (пользователей: 0 , гостей: 1)
|
|
Ваши права в разделе
|
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения
HTML код Выкл.
|
|
|
Часовой пояс GMT +6, время: 03:11.
|