Вернуться   Мегионский форум > Компьютеры и технологии > Программирование, компьютерное творчество

Ответ
 
Опции темы Поиск в этой теме
Старый 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
Почетный ветеран
 
Аватар для Kosting
 
Регистрация: 05.08.2003
Адрес: N61°3'E76°6' - Мегион
Сообщений: 5,498
Галерея: 67
Записей в дневнике: 66
Р: Kosting отключил(а) отображение уровня репутации
Контрольная на ASM. В самомодифицирующихся кодах ....

2 Игорь
Это я подправил - [code ] поставил, читается лучше...
Kosting вне форума   Ответить с цитированием
Старый 28.03.2005, 09:58   #3
Земляк
 
Аватар для Игорь
 
Регистрация: 24.12.2003
Адрес: Уже не из Мегиона
Сообщений: 785
Галерея: 0
Р: Игорь скоро придёт к известности Игорь скоро придёт к известности
Контрольная на ASM. В самомодифицирующихся кодах ....

Цитата:
Сообщение от Kosting
2 Игорь
Это я подправил - [code ] поставил, читается лучше...
Согласен, но пргрмму писал в состоянии сильного изменения
сознания на коленке и за адын вечер, чтобы утром отдать
преподу ( хотелось сказать - бррросить в его гадскую морду ) ... ;-)

P.S. Вообще - куча всяких контрольных от ASM'а осталась - кому
из Томских политехников надо-ть - пишите - отдам нафих ...
Могу и тулзы всякие по мелочам ...
__________________
-----------------
С уважением:
Игорь
Игорь вне форума   Ответить с цитированием
Старый 09.04.2007, 22:49   #4
Гайка
 
Аватар для Gaido
 
Регистрация: 20.08.2003
Сообщений: 9,650
Галерея: 1
Записей в дневнике: 1
Р: Gaido репутация неоспорима Gaido репутация неоспорима Gaido репутация неоспорима Gaido репутация неоспорима Gaido репутация неоспорима Gaido репутация неоспорима Gaido репутация неоспорима Gaido репутация неоспорима Gaido репутация неоспорима Gaido репутация неоспорима Gaido репутация неоспорима
Контрольная на ASM. В самомодифицирующихся кодах ....

можешь на почту кинуть контрольные свои?
__________________
«Ведь я только всего и хочу, чтобы все всегда было по-моему» Б.Шоу
Gaido вне форума   Ответить с цитированием
Старый 10.04.2007, 08:51   #5
Земляк
 
Аватар для Игорь
 
Регистрация: 24.12.2003
Адрес: Уже не из Мегиона
Сообщений: 785
Галерея: 0
Р: Игорь скоро придёт к известности Игорь скоро придёт к известности
Re: Контрольная на ASM. В самомодифицирующихся кодах ....

Цитата:
Сообщение от Gaido
можешь на почту кинуть контрольные свои?
Аддрессс !!!

В ICQ постучался - а тишинаааа ...
__________________
-----------------
С уважением:
Игорь
Игорь вне форума   Ответить с цитированием
Старый 11.04.2007, 01:14   #6
Гайка
 
Аватар для Gaido
 
Регистрация: 20.08.2003
Сообщений: 9,650
Галерея: 1
Записей в дневнике: 1
Р: Gaido репутация неоспорима Gaido репутация неоспорима Gaido репутация неоспорима Gaido репутация неоспорима Gaido репутация неоспорима Gaido репутация неоспорима Gaido репутация неоспорима Gaido репутация неоспорима Gaido репутация неоспорима Gaido репутация неоспорима Gaido репутация неоспорима
Контрольная на ASM. В самомодифицирующихся кодах ....

ответила в аську. Заранее спасибо
__________________
«Ведь я только всего и хочу, чтобы все всегда было по-моему» Б.Шоу
Gaido вне форума   Ответить с цитированием
Старый 11.04.2007, 09:18   #7
Земляк
 
Аватар для Игорь
 
Регистрация: 24.12.2003
Адрес: Уже не из Мегиона
Сообщений: 785
Галерея: 0
Р: Игорь скоро придёт к известности Игорь скоро придёт к известности
Re: Контрольная на ASM. В самомодифицирующихся кодах ....

Цитата:
Сообщение от Gaido
ответила в аську. Заранее спасибо
Выслал всё что было со старых времён ...
__________________
-----------------
С уважением:
Игорь
Игорь вне форума   Ответить с цитированием
Ответ
Вернуться   Мегионский форум > Компьютеры и технологии > Программирование, компьютерное творчество


Здесь присутствуют: 1 (пользователей: 0 , гостей: 1)
 

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.

Быстрый переход


Часовой пояс GMT +6, время: 22:45.


Powered by vBulletin® Version 3.8.6
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd. Перевод: zCarot
© megion.net

Rambler's Top100