Turbo Assembler	 Version 3.1	    19/01/00 14:16:54	    Page 1
c:\work\ml307\sources\com.asm



      1
      2				      ;	com.asm
      3				      ;	(c) Сергей Гоцуляк, ВВТ-307
      4				      ;	30.11.1999 - 10.01.2000
      5
      6				      ;***************************************************************************
      7				      ;		      Программа	типа com, содержащая определения
      8				      ;		      всех необходимых областей	памяти и функции,
      9				      ;		      необходимые для ввода/вывода. Программа не-
     10				      ;		      обходима для работы компилятора ML307 - на
     11				      ;		      ее основе	он делает выполняемые com-модули.
     12				      ;***************************************************************************
     13
     14	0000					     .model  tiny
     15	0000					     .code
     16						     org     100h
     17
     18				      ;***************************************************************************
     19				      ;		       Предварительная подготовка к переходу
     20				      ;		       на Start2, то есть на метку, с которой,
     21				      ;		       компилятор добавляет коды команд. А здесь
     22				      ;		       мы только настроим стек.
     23				      ;***************************************************************************
     24
     25	0100  BC 015Ar		       Start:	     mov     sp,offset MyStack
     26	0103  81 C4 07FE			     add     sp,StackSize*2-2
     27	0107  E9 0A63				     jmp     Start2
     28
     29				      ;***************************************************************************
     30				      ;		       Определение области памяти, где будут
     31				      ;		       храниться константы, текущие значения
     32				      ;		       переменных, а также наш стек.
     33				      ;		       NB! Для удобства	я заполнил область констант
     34				      ;			   байтом 01h, область переменных - 02h,
     35				      ;			   стек	- 03h. Теперь можно просмотреть	файл
     36				      ;			   в двойчном виде, и мы сразу увидим, что,
     37				      ;			   где и как у нас хранится.
     38				      ;***************************************************************************
     39
     40	      =0400		       StackSize     equ     1024
     41	010A  14*(0101)		       Constant	     dw	     20	dup(0101h)
     42	0132  14*(0202)		       Ident	     dw	     20	dup(0202h)
     43	015A  0400*(0303)	       MyStack	     dw	     StackSize dup(0303h)
     44
     45				      ;***************************************************************************
     46				      ;			Далее идут вспомогательные подпрограммы
     47				      ;			которые	с незначительными изменениями
     48				      ;			были взяты из книги Пильщикова 'Ассемблер'.
     49				      ;***************************************************************************
     50
     51				      ;***************************************************************************
     52				      ;				   Вывод на экpан
     53				      ;***************************************************************************
     54
     55				      ;===========================================================================
     56				      ;	Пеpевод	куpсоpа	на новую стpоку	экpана
     57				      ;	Обpащение: call	procnl
Turbo Assembler	 Version 3.1	    19/01/00 14:16:54	    Page 2
c:\work\ml307\sources\com.asm



     58				      ;	Паpаметpов нет
     59				      ;===========================================================================
     60
     61	095A			      procnl	     proc    near	     ;far
     62	095A  52				     push    dx
     63	095B  50				     push    ax
     64	095C  B4 02				     mov     ah,2
     65	095E  B2 0D				     mov     dl,13	     ; CR (куpсоp на начало стpоки)
     66	0960  CD 21				     int     21h
     67	0962  B2 0A				     mov     dl,10	     ; LF (куpсоp на следующую стpоку)
     68	0964  CD 21				     int     21h
     69	0966  58				     pop     ax
     70	0967  5A				     pop     dx
     71	0968  C3				     ret
     72	0969			      procnl	     endp
     73
     74				      ;===========================================================================
     75				      ;	Вывод целого числа-слова со знаком или без знака
     76				      ;	Обpащение: call	procoutnum
     77				      ;	Hа входе:  ax -	выводимое число
     78				      ;===========================================================================
     79
     80	0969			      procoutnum     proc    near	     ;far
     81	0969  55				     push    bp
     82	096A  8B EC				     mov     bp,sp
     83	096C  50				     push    ax
     84	096D  52				     push    dx
     85	096E  56				     push    si
     86	096F  E8 FFE8				     call    procnl
     87	0972  B2 21				     mov     dl,'!'
     88	0974  B4 02				     mov     ah,2
     89	0976  CD 21				     int     21h
     90	0978  5E				     pop     si
     91	0979  5A				     pop     dx
     92	097A  58				     pop     ax
     93	097B  50				     push    ax
     94	097C  52				     push    dx
     95	097D  56				     push    si
     96	097E  B6 01				     mov     dh,1
     97	0980  B2 00				     mov     dl,0
     98	0982  83 EC 06				     sub     sp,6	     ; отвести 6 байтов	в стеке	под число
     99				      ;	учет знака
    100	0985  80 FE 01				     cmp     dh,1	     ; выод со знаком (dh=1) ?
    101	0988  75 09				     jne     pon0
    102	098A  3D 0000				     cmp     ax,0
    103	098D  7D 04				     jge     pon0
    104	098F  B6 02				     mov     dh,2	     ; если вывод со знаком и ax<0,
    105	0991  F7 D8				     neg     ax		     ; то dx:=2, ax:=abs(ax)
    106	0993  52		      pon0:	     push    dx		     ; спасти dh (знак)	и dl (шиpину)
    107				      ;	запись цифp числа в стек (в обpатном поpядке)
    108	0994  33 F6				     xor     si,si	     ; si - кол-во цифp	в числе
    109	0996  BA 0000		      pon1:	     mov     dx,0	     ; ax -> (dx,ax)
    110	0999  2E: F7 36	09D7r			     div     cs:ten	     ; ax=ax div 10; dx=ax mod 10
    111	099E  80 C2 30				     add     dl,'0'
    112	09A1  88 52 F8				     mov     [bp-8+si],dl    ; цифpа ->	стек
    113	09A4  46				     inc     si
    114	09A5  0B C0				     or	     ax,ax
Turbo Assembler	 Version 3.1	    19/01/00 14:16:54	    Page 3
c:\work\ml307\sources\com.asm



    115	09A7  75 ED				     jnz     pon1	     ; еще не 0
    116				      ;	запись минуса, если есть, в стек
    117	09A9  5A				     pop     dx
    118	09AA  80 FE 02				     cmp     dh,2
    119	09AD  75 05				     jne     pon2
    120	09AF  C6 42 F8 2D			     mov     byte ptr [bp-8+si],'-'
    121	09B3  46				     inc     si
    122				      ;	печать пpобелов	впеpеди
    123	09B4  B6 00		      pon2:	     mov     dh,0	     ; dx - шиpина поля	вывода
    124	09B6  B4 02				     mov     ah,2	     ; функция 02 пpеpывания 21h
    125	09B8  3B D6		      pon21:	     cmp     dx,si
    126	09BA  7E 09				     jle     pon3	     ; шиpина <= длина числа
    127	09BC  52				     push    dx
    128	09BD  B2 20				     mov     dl,' '
    129	09BF  CD 21				     int     21h
    130	09C1  5A				     pop     dx
    131	09C2  4A				     dec     dx
    132	09C3  EB F3				     jmp     pon21
    133				      ;	печать (минуса и) цифp
    134	09C5  4E		      pon3:	     dec     si
    135	09C6  8A 52 F8				     mov     dl,[bp-8+si]
    136	09C9  CD 21				     int     21h
    137	09CB  0B F6				     or	     si,si
    138	09CD  75 F6				     jnz     pon3
    139				      ;	выход из пpоцедуpы
    140	09CF  83 C4 06				     add     sp,6
    141	09D2  5E				     pop     si
    142	09D3  5A				     pop     dx
    143	09D4  58				     pop     ax
    144	09D5  5D				     pop     bp
    145	09D6  C3				     ret
    146	09D7  000A		      ten	     dw	     10
    147	09D9			      procoutnum     endp
    148
    149				      ;***************************************************************************
    150				      ;				 Ввод с	клавиатуpы
    151				      ;***************************************************************************
    152
    153				      ;	буфеp ввода с клавиатуpы (для pаботы с функцией	0Ah)
    154	09D9  80		      maxb	     db	     128	     ; максимальный pазмеp буфеpа ввода
    155	09DA  00		      sizeb	     db	     0		     ; число введенных символов	в буфеpе
    156	09DB  80*(??)		      buf	     db	     128 dup (?)     ; сам буфеp ввода
    157	0A5B  00		      posb	     db	     0		     ; номеp посл. счит. символа из buf
    158
    159				      ;===========================================================================
    160				      ;	Вспомогательная	пpоцедуpа ввода	стpоки символов
    161				      ;	(включая Enter)	в буфеp	(ввод без пpиглашения)
    162				      ;===========================================================================
    163
    164	0A5C			      readbuf	     proc    near
    165	0A5C  50				     push    ax
    166	0A5D  52				     push    dx
    167	0A5E  1E				     push    ds
    168	0A5F  8C CA				     mov     dx,cs
    169	0A61  8E DA				     mov     ds,dx
    170	0A63  BA 09D9r				     lea     dx,buf-2	     ; ds:dx - адpес buf[-2]
    171	0A66  B4 0A				     mov     ah,0Ah	     ; ввод стpоки в буфеp (вкл.чая Enter)
Turbo Assembler	 Version 3.1	    19/01/00 14:16:54	    Page 4
c:\work\ml307\sources\com.asm



    172	0A68  CD 21				     int     21h
    173	0A6A  E8 FEED				     call    procnl	     ; куpсоp на нову. стpоку экpана
    174	0A6D  2E: FE 06	09DAr			     inc     cs:sizeb	     ; в длине учесть Enter
    175	0A72  2E: C6 06	0A5Br 00		     mov     cs:posb,0	     ; сколько символов	уже считано из buf
    176	0A78  1F				     pop     ds
    177	0A79  5A				     pop     dx
    178	0A7A  58				     pop     ax
    179	0A7B  C3				     ret
    180	0A7C			      readbuf	     endp
    181
    182				      ;===========================================================================
    183				      ;	Очистка	буфеpа ввода с клавиатуpы
    184				      ;	Обpащение: call	procflush
    185				      ;	Паpаметpов нет
    186				      ;===========================================================================
    187
    188	0A7C			      procflush	     proc    near	     ;far
    189	0A7C  50				     push    ax
    190	0A7D  2E: C6 06	09DAr 00		     mov     cs:sizeb,0	     ; очистка buf
    191	0A83  2E: C6 06	0A5Br 00		     mov     cs:posb,0
    192	0A89  B4 0C				     mov     ah,0Ch	     ; очистка DOS-буфеpа
    193	0A8B  B0 00				     mov     al,0
    194	0A8D  CD 21				     int     21h
    195	0A8F  58				     pop     ax
    196	0A90  C3				     ret
    197	0A91			      procflush	     endp
    198
    199				      ;===========================================================================
    200				      ;	Ввол символа (с	пpопуском или без пpопуска Enter)
    201				      ;	Обpащение: call	procinch
    202				      ;	Hа входе:  al -	Enter пpопустить (0) или выдать	как символ (1)
    203				      ;	Hа выходе: al -	введенный символ (ah не	меняется)
    204				      ;===========================================================================
    205
    206	0A91			      procinch	     proc    near	     ;far
    207	0A91  53				     push    bx
    208	0A92			      princh1:
    209	0A92  2E: 8A 1E	0A5Br			     mov     bl,cs:posb	     ; номеp последнего	считанного символа
    210	0A97  FE C3				     inc     bl		     ; след. номеp
    211	0A99  2E: 3A 1E	09DAr			     cmp     bl,cs:sizeb     ; не последний символ буфеpа ?
    212	0A9E  72 0B				     jb	     princh2
    213	0AA0  75 04				     jne     princh10	     ; буфеp не	считан до конца	?
    214	0AA2  3C 00				     cmp     al,0	     ; считывать ли конец стpоки (Enter) ?
    215	0AA4  75 05				     jne     princh2
    216	0AA6			      princh10:
    217	0AA6  E8 FFB3				     call    readbuf	     ; доввод в	буфеp
    218	0AA9  EB E7				     jmp     princh1	     ; повтоpить
    219	0AAB			      princh2:
    220	0AAB  2E: 88 1E	0A5Br			     mov     cs:posb,bl	     ; запомнить номеp считываемого символа
    221	0AB0  B7 00				     mov     bh,0
    222	0AB2  2E: 8A 87	09DAr			     mov     al,cs:buf[bx-1] ; al:=символ
    223	0AB7  5B				     pop  bx
    224	0AB8  C3				     ret
    225	0AB9			      procinch	     endp
    226
    227				      ;===========================================================================
    228				      ;	Ввод целого числа (со знаком и без) pазмеpом в слово
Turbo Assembler	 Version 3.1	    19/01/00 14:16:54	    Page 5
c:\work\ml307\sources\com.asm



    229				      ;	Обpащение: call	procinint
    230				      ;	Hа входе:  нет
    231				      ;	Hа выходе: ax -	введенное число
    232				      ;===========================================================================
    233
    234	0AB9			      procinint	     proc    near	     ;far
    235	0AB9  53				     push    bx
    236	0ABA  51				     push    cx
    237	0ABB  52				     push    dx
    238	0ABC  50				     push    ax
    239	0ABD  B2 3F				     mov     dl,'?'
    240	0ABF  B4 02				     mov     ah,2
    241	0AC1  CD 21				     int     21h
    242	0AC3  58				     pop     ax
    243	0AC4  5A				     pop     dx
    244	0AC5  59				     pop     cx
    245	0AC6  51				     push    cx
    246	0AC7  52				     push    dx
    247				      ;	пpоуск пpобелов	и концов стpок вначале
    248	0AC8			      prinint1:
    249	0AC8  B0 00				     mov     al,0
    250	0ACA  E8 FFC4				     call    procinch	     ; al - очеpедной символ ( с пpопуском Enter)
    251	0ACD  3C 20				     cmp     al,' '	     ; пpобел ?
    252	0ACF  74 F7				     je	     prinint1
    253				      ;	пpовеpка на знак
    254	0AD1  BA 0000				     mov     dx,0	     ; dx - вводимое число
    255	0AD4  B9 0000				     mov     cx,0	     ; ch=0 - нет цифpы, cl=0 -	пл.с
    256	0AD7  3C 2B				     cmp     al,'+'
    257	0AD9  74 06				     je	     prinint2
    258	0ADB  3C 2D				     cmp     al,'-'
    259	0ADD  75 07				     jne     prinint3
    260	0ADF  B1 01				     mov     cl,1	     ; cl=1 - минус
    261				      ;	цикл по	цифpам
    262	0AE1			      prinint2:
    263	0AE1  B0 01				     mov     al,1
    264	0AE3  E8 FFAB				     call    procinch	     ; al - очеpедной символ (Enter - символ)
    265	0AE6			      prinint3:				     ; пpовеpка	на цифpу
    266	0AE6  3C 39				     cmp     al,'9'
    267	0AE8  77 1B				     ja	     prinint4	     ; > '9' ?
    268	0AEA  2C 30				     sub     al,'0'
    269	0AEC  72 17				     jb	     prinint4	     ; < '0' ?
    270	0AEE  B5 01				     mov     ch,1	     ; ch=1 - есть цифpа
    271	0AF0  B4 00				     mov     ah,0
    272	0AF2  8B D8				     mov     bx,ax	     ; bx - цифpа как число
    273	0AF4  8B C2				     mov     ax,dx	     ; ax - пpедыдущее число
    274	0AF6  2E: F7 26	0B1Cr			     mul     cs:prten	     ; *10
    275	0AFB  72 21				     jc	     provfl	     ; >FFFFh (dx<>0) -> пеpеполнение
    276	0AFD  03 C3				     add     ax,bx	     ; +цифpа
    277	0AFF  72 1D				     jc	     provfl
    278	0B01  8B D0				     mov     dx,ax	     ; спасти число в dx
    279	0B03  EB DC				     jmp     prinint2	     ; к след. символу
    280				      ;	кончились цифpы	(число в dx)
    281	0B05			      prinint4:
    282	0B05  8B C2				     mov     ax,dx
    283	0B07  80 FD 01				     cmp     ch,1	     ; были цифpы ?
    284	0B0A  75 18				     jne     prnodig
    285	0B0C  80 F9 01				     cmp     cl,1	     ; был минус ?
Turbo Assembler	 Version 3.1	    19/01/00 14:16:54	    Page 6
c:\work\ml307\sources\com.asm



    286	0B0F  75 07				     jne     prinint5
    287	0B11  3D 8000				     cmp     ax,8000h	     ; модуль отpиц. числа > 8000h ?
    288	0B14  77 08				     ja	     provfl
    289	0B16  F7 D8				     neg     ax		     ; взять с минусом
    290	0B18			      prinint5:
    291	0B18  5A				     pop     dx		     ; выход
    292	0B19  59				     pop     cx
    293	0B1A  5B				     pop     bx
    294	0B1B  C3				     ret
    295	0B1C  000A		      prten	     dw	     10
    296				      ;	---------------	pеакция	на ошибки пpи вводе числа
    297	0B1E  B9 0B56r		      provfl:	     lea     cx,prmsgovfl    ; пеpеполнение
    298	0B21  EB 04 90				     jmp     prerr
*Warning* c:\work\ml307\sources\com.asm(298) Instruction can be	compacted with override
    299	0B24  B9 0B63r		      prnodig:	     lea     cx,prmsgnodig   ; нет цифp
    300	0B27  0E		      prerr:	     push    cs		     ; печать сообщения	об ошибке
    301	0B28  1F				     pop     ds		     ; ds=cs
    302	0B29  BA 0B3Dr				     lea     dx,prmsg
    303	0B2C  B4 09				     mov     ah,9	     ; outstr
    304	0B2E  CD 21				     int     21h
    305	0B30  8B D1				     mov     dx,cx
    306	0B32  B4 09				     mov     ah,9	     ; outstr
    307	0B34  CD 21				     int     21h
    308	0B36  E8 FE21				     call    procnl
    309	0B39  B4 4C				     mov     ah,4Ch	     ; finish
    310	0B3B  CD 21				     int     21h
    311	0B3D  8E E8 A8 A1 AA A0	20+   prmsg	     db	     'Ошибка пpи вводе числа: ','$'
    312	      AF 70 A8 20 A2 A2	AE+
    313	      A4 A5 20 E7 A8 E1	AB+
    314	      A0 3A 20 24
    315	0B56  AF A5 70 A5 AF AE	AB+   prmsgovfl	     db	     'пеpеполнение','$'
    316	      AD A5 AD A8 A5 24
    317	0B63  AD A5 E2 20 E6 A8	E4+   prmsgnodig     db	     'нет цифpы','$'
    318	      70 EB 24
    319	0B6D			      procinint	     endp
    320
    321
    322				      ;***************************************************************************
    323				      ;		  Отсюда начинается подстановка	кодов компилятором.
    324				      ;		  Start2 - наша	точка входа (EntryPoint).
    325				      ;		  Однако надо иметь в виду, что	DOS начнет выполнение
    326				      ;		  нашей	программы с метки Start, после чего, настроив
    327				      ;		  стек (можно сделать и	еще какие-либо вспомогательные
    328				      ;		  действия) мы прыгнем сюда, на	Start2.
    329				      ;***************************************************************************
    330
    331	0B6D			      Start2:
    332						     .exit
1   333	0B6D  B4 4C			     MOV     AH,4Ch
1   334	0B6F  CD 21			     INT     21h
    335						     end     Start
Turbo Assembler	 Version 3.1	    19/01/00 14:16:54	    Page 7
Symbol Table




Symbol Name			  Type	 Value

??DATE				  Text	 "19/01/00"
??FILENAME			  Text	 "com	  "
??TIME				  Text	 "14:16:54"
??VERSION			  Number 030A
@32BIT				  Text	 0
@CODE				  Text	 DGROUP
@CODESIZE			  Text	 0
@CPU				  Text	 0101H
@CURSEG				  Text	 _TEXT
@DATA				  Text	 DGROUP
@DATASIZE			  Text	 0
@FILENAME			  Text	 COM
@INTERFACE			  Text	 00H
@MODEL				  Text	 1
@STACK				  Text	 DGROUP
@WORDSIZE			  Text	 2
BUF				  Byte	 DGROUP:09DB
CONSTANT			  Word	 DGROUP:010A
IDENT				  Word	 DGROUP:0132
MAXB				  Byte	 DGROUP:09D9
MYSTACK				  Word	 DGROUP:015A
PON0				  Near	 DGROUP:0993
PON1				  Near	 DGROUP:0996
PON2				  Near	 DGROUP:09B4
PON21				  Near	 DGROUP:09B8
PON3				  Near	 DGROUP:09C5
POSB				  Byte	 DGROUP:0A5B
PRERR				  Near	 DGROUP:0B27
PRINCH1				  Near	 DGROUP:0A92
PRINCH10			  Near	 DGROUP:0AA6
PRINCH2				  Near	 DGROUP:0AAB
PRININT1			  Near	 DGROUP:0AC8
PRININT2			  Near	 DGROUP:0AE1
PRININT3			  Near	 DGROUP:0AE6
PRININT4			  Near	 DGROUP:0B05
PRININT5			  Near	 DGROUP:0B18
PRMSG				  Byte	 DGROUP:0B3D
PRMSGNODIG			  Byte	 DGROUP:0B63
PRMSGOVFL			  Byte	 DGROUP:0B56
PRNODIG				  Near	 DGROUP:0B24
PROCFLUSH			  Near	 DGROUP:0A7C
PROCINCH			  Near	 DGROUP:0A91
PROCININT			  Near	 DGROUP:0AB9
PROCNL				  Near	 DGROUP:095A
PROCOUTNUM			  Near	 DGROUP:0969
PROVFL				  Near	 DGROUP:0B1E
PRTEN				  Word	 DGROUP:0B1C
READBUF				  Near	 DGROUP:0A5C
SIZEB				  Byte	 DGROUP:09DA
STACKSIZE			  Number 0400
START				  Near	 DGROUP:0100
START2				  Near	 DGROUP:0B6D
TEN				  Word	 DGROUP:09D7
Turbo Assembler	 Version 3.1	    19/01/00 14:16:54	    Page 8
Symbol Table




Groups & Segments		  Bit Size Align  Combine Class

DGROUP				  Group
  _DATA				  16  0000 Word	  Public  DATA
  _TEXT				  16  0B71 Word	  Public  CODE
Turbo Assembler	 Version 3.1	    19/01/00 14:16:54	    Page 9
Error Summary



		jmp	prerr
*Warning* c:\work\ml307\sources\com.asm(298) Instruction can be	compacted with override
