litceymos.ru 1


Возможности макрогенератора

  • Текстовый препроцессор


Макроопределение - набор нескольких команд ассемблера, сгруппированных вместе под некоторым именем, и выполняющих некоторое законченное действие.

  • Макроопределение - набор нескольких команд ассемблера, сгруппированных вместе под некоторым именем, и выполняющих некоторое законченное действие.

  • Макровызов или макрокоманда, встречающаяся в тексте программы на языке ассемблера, вызывает замещение её на набор команд, вошедших в макроопределение.

  • Макроподстановка – процесс замены макрокоманды на набор команд из макроопределения.

  • Макрорасширение – набор команд вставленных в текст программы вместо макрокоманды.

  • Если макроопределение описано, макрокоманда его вызова может встречаться в любом месте программы.



.model tiny

  • .model tiny

  • .code org 256

  • Main proc mov dl,’*’ mov ah,2 int 21h

  • ret

  • Main endp end main



Макроопределения с параметром

  • Putstar macro mov dl,’*’ mov ah,2 int 21h endm

  • Putchar macro chr puch ax push dx mov ah,2 mov dl,chr int 21h pop dx pop ax endm


Формат макроса

  • Макроопределение Имя macro [арг1[:тип][,арг2[:тип]…]] список операторов endm

  • Тип аргументов REQ – при вызове всегда требуется явное указание соответствующего параметра. =<любая_строка> – если соответствующий пара-метр при вызове явно не указан, то подразумевается неявная инициализация его приведенным значением.

  • Макрокоманда Имя [парам1[,парам2…]]


Символы, имеющие специальный смысл

  • ;; - комментарии макроопределения не попа-дающие в макрорасширение (в отличие от ;)

  • & - ограничитель имени макро аргумента

  • % - признак вычисляемого константного выражения

  • < > - ограничитель значения макропараметра

  • ! – отмена специального смысла символа

  • Local метка – предписывает генерировать в макроподстановке не повторяющиеся метки.



Пример

  • Marray macro name,size,type:= Name d&type size dup(0) endm

  • P equ 10 Q equ 2

  • Marray array1,%P*Q,w array1 dw 20 dup(0)

  • Marray array2,P*Q array2 db P*Q dup(0)



Пример

  • Absax macro local met,fin cmp ax,8000h je fin Met: neg ax js met Fin: nop endp

  • … mov ax,2 absax mov ax,-5 absax



Библиотеки макроопределений

  • INCLUDE path:\file_name - включить содержимое файла в текст программы

  • PURGE name - указывает имена макроопределений, которые не должны использоваться при компиляции данной программы



Условные директивы IF*** xxxxx [ELSE операторы1 операторы3] [ELSEIF*** ENDIF операторы2]



Пример


Директивы повторения 1

  • REPT выражение

  • ENDM

  • .data k=0 rept 4 db k k=k+1 endm


Директивы повторения 2

  • IRP параметр,<аргументы> … ENDM

  • SaveReg macro RegList irp reg, push reg endm endm

  • SaveReg

  • IRP reg, push reg ENDM



.ERRxx n - условная директива увеличения значения счетчика числа ошибок. Может сообщать код ошибки n. (хх – те же символы, что и в IFxx)

  • .ERRxx n - условная директива увеличения значения счетчика числа ошибок. Может сообщать код ошибки n. (хх – те же символы, что и в IFxx)

  • %OUT текст – выводит на стандартный вывод текст сообщения об ошибке.

  • GOTO :met – директива безусловного перехода макрогенератора к строке макроопределения с внутренней меткой :met.



Пример

  • pushall macro r1,r2,r3,r4,r5,r6,r7,r8

  • ifnb

  • push r1

  • pushall r2,r3,r4,r5,r6,r7,r8

  • endif

  • endm

  • pushall ax,bx,cx

  • pushall ax,bx,cx,dx,sp,bp,si,di



Файл print.h

  • .486 .data cwr dw ? rq label qword rd label dword rab dt ? adr_rab dd rab+8



Пролог основной программы


Переход на новую строку

  • newline macro push ax push dx mov ah,2 mov dl,13 int 21h mov dl,10 int 21h pop dx pop ax

  • endm


Вывод текста из сегмента данных (должен заканчиваться знаком $)

  • pr_str macro str

  • push ax

  • push dx

  • mov ah,9

  • lea dx,str

  • int 21h

  • pop dx

  • pop ax

  • endm



Вывод k символов

  • pr_char macro c,k:=<1>

  • push ax

  • mov ah,2

  • ifdifi ,

  • push dx

  • mov dl,c

  • endif

  • ifidni ,

  • push cx

  • mov cx,bx

  • elseif k gt 1

  • push cx

  • mov cx,k

  • endif



pr_int macro x,m:=<1>

  • pr_int macro x,m:=<1>

  • local m1,m2,m3,m4,m5,m6,m7,m8,fin

  • pusha

  • if type x eq 1 push ax mov ah,x sar ax,8 mov word ptr rab,ax pop ax fild word ptr rab

  • else

  • fild x ; Загрузили в стек FPU целое число

  • endif


fbstp rab ; Выгрузили в память в BCD формате

  • fbstp rab ; Выгрузили в память в BCD формате

  • les di,adr_rab ; Старший байт - байт знака и ovfl

  • mov al,[di+1]

  • xor al,0ffh ; Если =FFh - переполнение

  • jnz short m1

  • pr_char '*',5 ; печатаем звездочки

  • jmp fin

  • m1: mov al,[di+1]

  • test al,80h ; Проверка знака

  • jz short m2

  • pr_char '-' ; Печатаем минус, если число <0

  • m2: std

  • mov cx,9 ; Обработка мантиссы

  • xor al,al


repe scasb ; Пропускаем старшие нули jz short m5 mov bx,cx inc bx shl bx,1 sub bl,m ; для дробной части ja short m6 jz short m8 neg bl ; печатаем ведущие нули pr_char '0',bx

  • repe scasb ; Пропускаем старшие нули jz short m5 mov bx,cx inc bx shl bx,1 sub bl,m ; для дробной части ja short m6 jz short m8 neg bl ; печатаем ведущие нули pr_char '0',bx

  • m8: mov bh,1

  • m6: mov dl,[di+1] ; Первый не нулевой байт shr dl,4 jnz short m3 test bh,1 jz short m7



repe scasb ; Пропускаем старшие нули jz short m5 mov bx,cx inc bx shl bx,1 sub bl,m ; для дробной части ja short m6 jz short m8 neg bl ; печатаем ведущие нули pr_char '0',bx

  • repe scasb ; Пропускаем старшие нули jz short m5 mov bx,cx inc bx shl bx,1 sub bl,m ; для дробной части ja short m6 jz short m8 neg bl ; печатаем ведущие нули pr_char '0',bx

  • m8: mov bh,1

  • m6: mov dl,[di+1] ; Первый не нулевой байт shr dl,4 jnz short m3 test bh,1 jz short m7



repe scasb ; Пропускаем старшие нули jz short m5 mov bx,cx inc bx shl bx,1 sub bl,m ; для дробной части ja short m6 jz short m8 neg bl ; печатаем ведущие нули pr_char '0',bx

  • repe scasb ; Пропускаем старшие нули jz short m5 mov bx,cx inc bx shl bx,1 sub bl,m ; для дробной части ja short m6 jz short m8 neg bl ; печатаем ведущие нули pr_char '0',bx

  • m8: mov bh,1

  • m6: mov dl,[di+1] ; Первый не нулевой байт shr dl,4 jnz short m3 test bh,1 jz short m7


m3: add dl,48 ; Цифра в старшем полубайте не нуль

  • m3: add dl,48 ; Цифра в старшем полубайте не нуль

  • pr_char dl

  • m7: mov dl,[di+1]

  • and dl,0fh ; Цифра из младшего полубайта

  • add dl,48

  • pr_char dl

  • jcxz short fin ; Переход если этот байт единственн.

  • mov si,di

  • m4: lodsb

  • mov dl,al

  • shr dl,4 ; Старший полубайт текущего байта

  • add dl,48

  • pr_char dl


m3: add dl,48 ; Цифра в старшем полубайте не нуль

  • m3: add dl,48 ; Цифра в старшем полубайте не нуль

  • pr_char dl

  • m7: mov dl,[di+1]

  • and dl,0fh ; Цифра из младшего полубайта

  • add dl,48

  • pr_char dl

  • jcxz short fin ; Переход если этот байт единственн.

  • mov si,di

  • m4: lodsb

  • mov dl,al

  • shr dl,4 ; Старший полубайт текущего байта

  • add dl,48

  • pr_char dl



m3: add dl,48 ; Цифра в старшем полубайте не нуль

  • m3: add dl,48 ; Цифра в старшем полубайте не нуль

  • pr_char dl

  • m7: mov dl,[di+1]

  • and dl,0fh ; Цифра из младшего полубайта

  • add dl,48

  • pr_char dl

  • jcxz short fin ; Переход если этот байт единственн.

  • mov si,di

  • m4: lodsb

  • mov dl,al

  • shr dl,4 ; Старший полубайт текущего байта

  • add dl,48

  • pr_char dl



mov dl,al

  • mov dl,al

  • and dl,0fh ; Младший полубайт текущего байта

  • add dl,48

  • pr_char dl

  • loop m4

  • jmp short fin

  • m5: pr_char '0',m ; Печать нулевого числа

  • fin: cld

  • popa

  • endm


print macro tp,x,after:=<5>

  • print macro tp,x,after:=<5>

  • local m,m1,k

  • ifidni ,

  • pr_int x ; Вывод целого числа со знаком

  • elseifidni ,

  • push ax ; Вывод целого без знака

  • k= (type x) /2

  • while k lt 3

  • mov word ptr rab + 2*k,0

  • k=k+1

  • endm


if type x eq 1

  • if type x eq 1

  • mov al,x

  • mov byte ptr rq,al

  • elseif type x eq 2

  • mov ax,x

  • mov word ptr rq,ax

  • elseif type x eq 4

  • mov eax,x

  • mov dword ptr rq,eax

  • else

  • Display "Error Type of Unsigned Parameter &x"

  • .err

  • exitm

  • endif

  • pop ax

  • pr_int rq



elseifidni ,

  • elseifidni ,

  • fstcw cwr ; Вывод вещественного числа

  • push cwr

  • and cwr,0f3ffh ; Установить режим отбрасывания or cwr,0c00h ; дробной части

  • fldcw cwr

  • fld x ; Загрузить в стек FPU вещественное число

  • fist rd ; сохранить в памяти целую часть

  • push rd

  • cmp rd,0

  • jnz short m1

  • ftst

  • fstsw ax

  • sahf

  • jae short m1

  • pr_char '-'



m1: pr_int rd ; и вывести её

  • m1: pr_int rd ; и вывести её

  • pr_char '.' ; Вывести десятичную точку

  • pop rd

  • fisub rd ; Вычислить дробную часть

  • ftst

  • fstsw ax

  • sahf

  • ja short m

  • fchs ; Изменить знак в случае отрицательного числа

  • m:

  • k=0

  • rept 5

  • mov word ptr rab + k,0

  • k=k+2

  • endm

if (after mod 2) eq 1

  • if (after mod 2) eq 1

  • mov byte ptr rab+(after shr 1),10h

  • else

  • mov byte ptr rab+(after shr 1),1

  • endif ; Определили сомножитель для выделения

  • fbld rab ; цифр после запятой

  • fmul

  • pop cwr ; Восстановить прежний режим работы FPU

  • fldcw cwr

  • fistp rd ; Сохранить целое число составленное из цифр,

  • pr_int rd,after ; стоящих после запятой и вывести его

  • else

  • Display "Error First Parameter"

  • .err

  • endif

  • endm



Вычисление функции xy

  • fpw macro x,y,z

  • local cnt

  • k= (type x) - 1

  • mov al,byte ptr (x+k)

  • test al,80h

  • jz short cnt

  • .exit 1

  • cnt: finit

  • fld y

  • fld x

  • fyl2x

  • fld st

  • frndint



Вычисление функции xy

  • fpw macro x,y,z

  • local cnt

  • k= (type x) - 1

  • mov al,byte ptr (x+k)

  • test al,80h

  • jz short cnt

  • .exit 1

  • cnt: finit

  • fld y

  • fld x

  • fyl2x

  • fld st

  • frndint


Вычисление функции xy

  • fpw macro x,y,z

  • local cnt

  • k= (type x) - 1

  • mov al,byte ptr (x+k)

  • test al,80h

  • jz short cnt

  • .exit 1

  • cnt: finit

  • fld y

  • fld x

  • fyl2x

  • fld st

  • frndint


Вычисление функции xy

  • fpw macro x,y,z

  • local cnt

  • k= (type x) - 1

  • mov al,byte ptr (x+k)

  • test al,80h

  • jz short cnt

  • .exit 1

  • cnt: finit

  • fld y

  • fld x

  • fyl2x

  • fld st

  • frndint



Вычисление функции xy

  • fpw macro x,y,z

  • local cnt

  • k= (type x) - 1

  • mov al,byte ptr (x+k)

  • test al,80h

  • jz short cnt

  • .exit 1

  • cnt: finit

  • fld y

  • fld x

  • fyl2x

  • fld st

  • frndint



Вычисление функции xy

  • fpw macro x,y,z

  • local cnt

  • k= (type x) - 1

  • mov al,byte ptr (x+k)

  • test al,80h

  • jz short cnt

  • .exit 1

  • cnt: finit

  • fld y

  • fld x

  • fyl2x

  • fld st

  • frndint



Вычисление функции xy

  • fpw macro x,y,z

  • local cnt

  • k= (type x) - 1

  • mov al,byte ptr (x+k)

  • test al,80h

  • jz short cnt

  • .exit 1

  • cnt: finit

  • fld y

  • fld x

  • fyl2x

  • fld st

  • frndint


Вычисление функции xy

  • fpw macro x,y,z

  • local cnt

  • k= (type x) - 1

  • mov al,byte ptr (x+k)

  • test al,80h

  • jz short cnt

  • .exit 1

  • cnt: finit

  • fld y

  • fld x

  • fyl2x

  • fld st

  • frndint


Вычисление функции xy

  • fpw macro x,y,z

  • local cnt

  • k= (type x) - 1

  • mov al,byte ptr (x+k)

  • test al,80h

  • jz short cnt

  • .exit 1

  • cnt: finit

  • fld y

  • fld x

  • fyl2x

  • fld st

  • frndint



Вычисление функции xy

  • fpw macro x,y,z

  • local cnt

  • k= (type x) - 1

  • mov al,byte ptr (x+k)

  • test al,80h

  • jz short cnt

  • .exit 1

  • cnt: finit

  • fld y

  • fld x

  • fyl2x

  • fld st

  • frndint



Вычисление функции xy

  • fpw macro x,y,z

  • local cnt

  • k= (type x) - 1

  • mov al,byte ptr (x+k)

  • test al,80h

  • jz short cnt

  • .exit 1

  • cnt: finit

  • fld y

  • fld x

  • fyl2x

  • fld st

  • frndint



Пример

  • .model small

  • .stack 256

  • include print.h

  • .data x dd -0.05 y dw -1234 z db 100 w dd 1048576.0

  • .code main proc .start fpw w,x print real,w



Пример

  • irp p, irpc u,ab inc u&&p endm endm


Пример

  • irpс u,& irp p, x&u&p ax,ax endm endm