Heresy #04

Кoдиm нa ПЦ: yрoк трeтий - Урoк трeтий: зaгрyжaть фaйл mы yжe ymeem, тeпeрь пoпрoбyem eгo _выгрyжaть_.

<b>Кoдиm нa ПЦ: yрoк трeтий</b> - Урoк трeтий: зaгрyжaть фaйл mы yжe ymeem, тeпeрь пoпрoбyem eгo _выгрyжaть_.


####################  ####################                      
#########  ########## #########        ###                      
#########   ######### ########                                  
#########   ######### #######     ######  #####   #######       
#########  ########## #######     ######  ######        #       
#################### ########          # #######        #       
#########           ##########                                  
#########            ##########        ###                      
######### a$h         ####################                      

(c) Demiurge Ash                                                

    Урок третий: загружать файл мы уже ymeem,                   
    теперь попробуем его _выгружать_.                           
|   Пояснения сразу даются по тексту исходника.                 
+----------------------- - -                                    

;---------------ПрогРамМа N1------------------------------------
   .MODEL tiny                                                  
   .CODE                                                        
        ORG 100h                                                
start:                                                          
;--открытие файла------------                                   
       xor cx,cx           ;установка атрибутов файла           
                           ; cx = 00h - обычный файл            
                           ;      01h - только для чтения       
                           ;      02h - скрытый файл            
                           ;      04h - системный               
       mov dx,offset FILE  ;указатель на ASCII строку,          
                           ;заканчивающуюся нулем, в            
                           ;которой указан путь к файлу         
       mov ax,ЗCOOh        ;подготовка вызова функции           
                           ;DOS для создания файла              
                           ;(если уже есть файл c таким же      
                           ;именем и y него нет атрибута        
                           ;только-чтение, то он уничтожается)  
       int 21h             ;вызов функции                       
       jc no_file                                               
;--запись файла--------------                                   
       mov bx,ax           ;передаем номер дескриптора          
       push bx             ;запоминаем дескриптор               
       mov cx,LEN          ;кол-во байт для записи              
       mov dx,offset DATA  ;адрес буфера                        
       mov ah,40h          ;подготовка вызова функции           
                           ;DOS для записи файла                
       int 21h             ;вызов функции                       
;--закрытие файла------------                                   
       pop bx              ;вспоминаем дескриптор               
       mov ah,ЗEh          ;norotobka вызова функции            
                           ;DOS закрытия файла                  
       int 21h             ;вызов функции                       
;--выход---------------------                                   
exit:                                                           
       mov ah,Чch                                               
       int 21h             ;выход в DOS                         

;--печать сообщения----------                                   
no_file:                                                        
       mov dx,offset MessЗ ;адрес первого сообщения             
print:                                                          
       mov ah,9                                                 
       int 21h             ;печать сообщений                    
       jmp exit                                                 
;---данные-------------------                                   

MessЗ   db 'I cant save file -your.dat- !!!',13,10,'$'          
FILE    db 'your.dat',0                                         
DATA    db 'a здесь должны находиться ваши данные, ',13,10      
        db 'которые вы хотите записать в файл...',13,10         
DATAEND db 0                                                    
LEN=DATAEND-DATA           ;подсчитываем размер cпиcывaemoгo    
                           ;буфера. Переменная LEN используется 
                           ;в процедуре записи файла.           
;----------------------------                                   
end start                                                       


+---------------------- --- -- - - -                            
|                                                               
    Все это набивается в любом редакторе (очень удобен для этого
встроеный  в Dos Navigator), затем списывается на диск, в файл c
расширением, к примеру, saver.asm                               
    Теперь,  если  y  вас  есть  ассемблер,  можно откомпилить в
com-файл. Через коммандную строку задаем:                       
    tasmx /m2 saver.asm                                         
и получаем объектный файл saver.obj, линкyem его в .com:        
    tlink /t /x saver.obj                                       
и лицезреем новый файл saver.com - запускайте!                  

 - -------------------------------- -                           

     Теперь  попробуем  изменять  информацию  в уже существующих
файлах,   например,   сделаем   camomoдифицирyющyюcя  программу,
которая будет изменять в своем файле счетчик ee запусков.       
     Заодно  сделаем процедуру рacпeчaтывaющyю число находящееся
в  шестнадцатиричной  форме, a также процедуру выводящую текст c
атрибутами.                                                     

;---------------ПрогРамМа N2------------------------------------
   .MODEL tiny                                                  
   .CODE                                                        
        ORG 100h                                                
start:                                                          
;--открытие файла------------                                   
       mov ax,3d01h        ;подготовка вызова функции DOS       
                           ;для открытия файла                  
                           ;(AL=01h - только для записи)        
       mov dx,offset FILE  ;путь к 'нашему' файлу               
       int 21h             ;вызов функции                       
       jb no_file          ;если такого файла нет, то переходим 
                           ;на ошибку открытия файла            
;--перемещение указателя-----                                   
       mov bx,ax           ;передаем номер дескриптора          
       push bx             ;запоминаем дескриптор               
       mov ax,4200h        ;подготовка вызова функции           
                           ;перемещения указателя в файле       
                           ;(AL=00h - относительно начала файла)
       xor cx,cx           ;пара СХ:DX указывает кол-во байт на 
       mov dx,Count-Start  ;которое надо сдвинуть указатель     
                           ;В нашем случае до переменной Count. 
       int 21h             ;вызов функции                       
;--изменение счетчика--------                                   
       inc [Count]         ;увеличиваем счетчик, размером в     
                           ;слово                               
;--печать счетчика-----------                                   

       mov dx,offset MessS ;адрес предисловия                   
       mov bl,2                                                 
       call print          ;печать предисловия                  

       xor si,si           ;обнуление индекса                   
       mov ax,[Count]      ;берем счетчик                       
       mov bx,offset Buff  ;oбoзнaчaem буфер                    
       mov cx,10           ;засылаем делитель                   
con1:  mov dx,0            ;обнуляем регистр для последующей    
                           ;засылки в него остатка              
       div cx              ;AL=AL/СХ, a остаток в DX            
       add dl,'0'          ;прибавляем к остатку код числа '0'  
       mov [bx+si],dl      ;и кидаем его в буфер                
       inc si              ;увеличиваем индекс                  
       or ax,ax            ;проверка, a может уже дoдeлилиcь    
                           ;до нуля?                            
       jnz con1            ;ежели нет, то делим дальше          
con2:  dec si              ;уменьшаем индекс                    
       mov dl,[bx+si]      ;достаем число                       
       mov ah,2            ;подготовка функции вывода символа   
                           ;находящегося в DL                   
       int 21h             ;вызов функции                       
       or si,si            ;если индекс ноль, то печатать больше
                           ;нечего                              
       jnz con2            ;переход если есть, что печатать     

       mov dx,offset Messб ;адрес послесловия                   
       mov bl,2                                                 
       call print                                               

;--запись в файл-------------                                   
       pop bx              ;вспоминаем дескриптор               
       mov ah,40h          ;подготовка вызова функции записи    
                           ;в файл                              
       mov dx,offset Count ;адрес буфера                        
       mov cx,2            ;кол-во байт для записи              
       int 21h             ;вызов функции                       
;--выход---------------------                                   
exit:                                                           
       mov ah,Чch                                               
       int 21h             ;выход в DOS                         
;--печать и выход------------                                   
no_file:                                                        
       mov dx,offset MessЧ ;адрес первого сообщения             
       mov bl,12                                                
       call print                                               
       jmp exit                                                 
;--печать сообщений----------                                   
print: call print1         ;вызов основной процедуры для        
                           ;распечатки сообщения                
       mov dx,offset Standart ;рacпeчaтывaниe пробела co        
       mov bl,07h          ;стандартными атрибутами для         
                           ;восстановления                      

print1:                                                         
       mov si,dx           ;адрес текста в индексный регистр    
       cld                 ;указываем направление изменения     
                           ;индексного регистра: "увеличение"   
next_symbol:                                                    
       lodsb               ;засылаем байт из [SI] в AL          
       or al,al            ;если ноль, то значит                
       jz p_exit           ;это конец сообщения                 
       mov ah,9            ;функция печати символа c атрибутом  
       xor bh,bh           ;номер видеостраницы - 0             
       mov cx,1            ;кол-во символов - 1                 
       cmp al,1Fh          ;проверяем символ на управляющий код 
       jbe sys_symbol      ;если да, то пропускаем печать       
                           ;атрибутов                           
       int 10h             ;вызов функции                       
sys_symbol:                                                     
       mov ah,OEh          ;функция телетайпа - выполнение      
                           ;управляющих кодов и передвижение    
                           ;курсора                             
       int 10h             ;вызов функции                       
       jmp next_symbol     ;следующий символ                    
p_exit:                                                         
       ret                 ;выход из процедуры                  
;---данные-------------------                                   

MessЧ   db 'I cant change file -our.com-',13,10,0               
MessS   db 'Program was started',0                              
Messб   db ' times',13,10,0                                     
Standart db 20h,0                                               
FILE    db 'our.com',0                                          
Count   dw 0000h                                                
Buff    db 5 DUP (?)                                            
;----------------------------                                   
end start                                                       

+---------------------- --- -- - - -                            
| Через коммандную строку задаем:                               
    tasmx /m2 our.asm                                           
и получаем объектный файл our.obj, линкyem его в .com:          
    tlink /t /x our.obj                                         
в итоге должен появиться файл our.com.                          
 - -------------------------------- -                           

     В  принципе, если вы умеете кодить на Спектруме, для вас не
составит  большого  труда  научится  писать приличные проги и на
ПЦ.  Здесь  главное разобраться как работать c аппаратной частью
компьютера:  c винтом, c экраном, c ayдиoкaртoчкoй и т.п., a все
алгоритмы  остаются прежними. Меняются лишь мнемоники их записи,
ну  и некоторые нюансы в связи c новыми командами. Так например 
привычная нам "магическая формула переноса информации" ;-)      

       LD HL,SOURCE                                             
       LD DE,DESTINATION                                        
       LD BC,SIZE                                               
       LDIR                                                     

     превращается в конструкцию вида:                           

      cld                       ;указываем направление          
                                ;изменения индексного регистра: 
                                ;"увеличение". Его можно        
                                ;изменить на STD - "уменьшение" 
                                ;(т.e. направление LDDR)        
      mov si,offset Source      ;помните, что данные берутся из 
      mov di,offset Destination ;пары регистров DS:SI и         
                                ;кидаются по адресу ES:DI и     
                                ;возможно потребуется           
                                ;корректировка регистров DS и ES
      mov cx,How                ;кол-во пересылаемых байт, a    
                                ;точнее кол-во повторов команды 
      rep movsb                 ;приставка rep является         
                                ;префиксом повторения, она      
                                ;заставляет следующую команду   
                                ;выполняться СХ раз.            
                                ;И наконец, команда movsb       
                                ;пересылает байт. Вместо нее    
                                ;можно использовать также       
                                ;команду movsw - пересылка      
                                ;слова                          
     В  одном  из  номеров  Harm'a Dr.Shizer предлагает заменять
команду                                                         
     ...                                                        
     rep movsb                                                  

     на конструкцию вида                                        

     ...                                                        
     shr cx,1                                                   
     rep movsw                                                  
     adc cx,cx                                                  
     rep movsb                                                  

     т.e.  все,  что  можем, кидаем словами, a остаток - байтом.
Прoгрыш в размере, выигрыш во времени!                          



Другие статьи номера:

Sketches among the Ruins of my Mind - Нaрeкaния вызвaлo изmeнeниe рeжиma выбoрa cтaтeй в глaвнom meню АКА "Frame must die".

Трyднo ли нe быть Бoгom - Стрyгaцких читaли вce. Их нeльзя нe читaть. Eщe их - кaк бecплaтный дoвecoк - нeльзя нe любить. А тo ты - нe интeллигeнт, a чeрт знaeт чтo.

ZХ-Land: Х-Project Аssociation - Взгляд изнyтри - В этoй рyбрикe я бы хoтeл знaкomить вac c гoрoдamи, в кoтoрых Speccy coхрaняeт eщe cвoи пoзиции...

Кoдиm нa ПЦ: yрoк трeтий - Урoк трeтий: зaгрyжaть фaйл mы yжe ymeem, тeпeрь пoпрoбyem eгo _выгрyжaть_.

Ocкoлки Mыcлeй - Pyбрикa, гдe кaждый moг бы выcкaзaтьcя o чem yгoднo, любoй "зaгрyз" нa любyю тemy.

ЗЫPКАЛO by Jam - Лицa, кoтoрыe пoпытaютcя нaйти в этom пoвecтвoвaнии moтив, бyдyт oтдaны пoд cyд...

Дoктрины Тeлemcкoгo Аббaтcтвa by Алeйcтeр Крoyли - В фигyрe Сaтaны oни вcлeд зa Крoyли ищyт yвeрeннocти в ceбe, бeзoпacнocти в mирe.

Слaвянcкoe Язычecтвo и Хриcтиaнcтвo - Прeoбрaзoвaниe пoзнaния прирoды в эmoциях я нaзвaл бы рeлигиeй.

АMБАPКАНТА by Дж.P.P.Тoлкин - Илюрamбaр (Ilurambar) или mирoвыe cтeны oгрaждaют вecь mир...

Стихи - My Poems by Werewolves.

Стихи - ВamпиP by Midnight Аngel.

I-Net Storyz - Пoчemy-тo бoльшинcтвo cmeшных иcтoрий прoиcхoдит или co cтyдeнтamи или вoкрyг них...

Приложение - Presentation, WanТeD.


Темы: Игры, Программное обеспечение, Пресса, Аппаратное обеспечение, Сеть, Демосцена, Люди, Программирование

Похожие статьи:
Music found - разговор об Музыкальныx редактораx для ZX Spectrum.
Hard-1 - устройство Midi интерфейса.
Грязное белье - Выход газеты bbsTOP #5.
События - демопати MilleniuM. Новая информация.
Сто рассказов о чукче - пpедлaгaемые aнекдoты не нoсят ни в кoей меpе нaциoнaлистическoгo хapaктеpa.

В этот день...   21 ноября