У нас: 141825 рефератів
Щойно додані Реферати Тор 100
Скористайтеся пошуком, наприклад Реферат        Грубий пошук Точний пошук
Вхід в абонемент


<число>*<змінна>

imul ax, [si+<змінна>],<число>

5(6)

<змінна>*@ або @*<змінна>

imul [si+<змінна>]

3(4)

<число>*@ або @*<число>

imul ax,<число>

4

<змінна1>/<змінна2>

xor dx,dx

mov ax,<змінна1>

idiv [si+<змінна2>]

9(10)

<змінна>/<число>

xor dx,dx

mov ax,<змінна>

mov bx, <число>

idiv bx

10

<число>/<змінна>

xor dx,dx

mov ax,<число>

idiv [si+<змінна>]

8(9)

КП.КС-05.00.00.000 ПЗ | Арк.

12

Зм. | Арк. | № докум | Підпис | Дата

Продовження таблиці 1

Конструкція

Асемблер

Довжина коду

(байт)

<змінна>/@

xor dx,dx

mov bx, [si+<змінна>]

xchg ax,bx

idiv bx

8(9)

@/<змінна>

xor dx,dx

idiv [si+<змінна>]

5(6)

<число>/@

xor dx,dx

mov bx, <число>

xchg ax,bx

idiv bx

8

@/<число>

xor dx,dx

mov bx, <число>

idiv bx

7

Для зменшення розміру програми використовується індексна адресація, базою якої є регістр SI з нульовим значенням. Звертання до перших 59 змінних дозволяє зменшити довжину багатьох конструкцій на 1 байт (використовується однобайтове зміщення, що розширюється знаком до 16 біт). В дужках вказана довжина конструкції в гіршому випадку.

Програма формує вихідний файл з текстом програми на мові Асемблер для компілятора Borland Turbo Assembler з використанням повних директив сегментації. Текст програми компілюється в *.exe файл шляхом виклику програм tasm.exe та tlink.exe через функцію system().

Нижче наведений шаблон для формування тексту програми:

.386 ; дозволити використання

; команд процесора 80386

.387 ; дозволити використання

; команд співпроцесора 80387

stack segment use16 ; сегмент стеку розміром 256

db 256 dup(?) ; байт з використанням

stack ends ; 16-розрядної адресації

data segment use16 ; початок сегменту даних

КП.КС-05.00.00.000 ПЗ | Арк.

13

Зм. | Арк. | № докум | Підпис | Дата

conv dt 0 ; 10 байт для роботи з 80387

<назва_змінної_1> DW <значення_змінної_1> ; ініціалізація змінних

;--------------------------------------------------------

<назва_змінної_N> DW <значення_змінної_N> ;

data ends ; кінець сегменту даних

code segment use16 ; початок сегменту коду

assume cs:code, ds:data, ss:stack ; об’явлення сегментів

main: mov ax,data ; ініціалізація сегменту

mov ds,ax ; даних

mov ax,stack ; ініціалізація сегменту

mov ss,ax ; стеку

mov sp,256 ; ініціалізація покажчика стеку

xor si,si ; SI=0

; текст основної програми

mov ah,1 ; виклик переривання DOS

int 21h ; для очікування натиснення

; кнопки на клавіатурі

mov ah,4Ch ; виклик переривання DOS

int 21h ; для завершення програми

; текст підпрограм вводу/виводу

code ends ; кінець сегменту коду

end main ; кінець модуля

Робота з програмою виглядає наступним чином. Для запуску програми слід ввести її назву в командний рядок разом з параметром (шлях до вхідного файлу, що транслюється). Після роботи програми в директорії, в якій вона знаходиться, з’являться вихідний файл res.asm, виконавчий файл скомпільованої програми res.exe та допоміжні файли компілятора. Після цього залишається лише запустити res.exe. В директорії програми обов’язково мають знаходитися файли input_r.txt та print_r.txt!

КП.КС-05.00.00.000 ПЗ | Арк.

14

Зм. | Арк. | № докум | Підпис | Дата

4 ТЕКСТ ПРОГРАМИ

#include <stdio.h> // Функції стандартних вводу/виводу

#include <string.h> // Функції роботи з рядками

#include <ctype.h> // Функції визначення типу байту

#include <stdlib.h> // Бібліотека стандартних функцій

char in[512], // Масив вхідного файлу

id[30][32], // Таблиця ідентифікаторів

var[32], // Назва зчитаного ідентифікатора

ex[90], // Масив арифметичного виразу

op1[30], op2[30], // Операнди арифметичної операції

pr[90], // Масив пріоритетів у виразі

d, // Прапорець присвоєння значення числа

found, // Прапорець повтору ідентифікатора

new_entry, // Прапорець нового ідентифікатора

oper, // Символ арифметичної операції

imm1, imm2, // Прапорці типу операндів (1-число)

k, e, // Покажчики масивів

v, // Прапорець присвоєння значення змінної

l, // Довжина виразу

current, // Поточний пріоритет елементу виразу

number, // Прапорець послідовності цифр

L1, L2, // Довжини операндів

shift, // Значення для зсуву виразу

max; // Максимальний пріоритет у виразі

int i, // Покажчик масиву вхідного файлу

filesize, // Розмір вхідного файлу

max_id; // Число ідентифікаторів у таблиці

FILE *fin,*fout; // Покажчики дескрипторів файлів

int main(int argc,char**argv)

{

КП.КС-05.00.00.000 ПЗ | Арк.

15

Зм. | Арк. | № докум | Підпис | Дата

if((fin=fopen(argv[1],"r"))==NULL) // Відкриття файлу з перевіркою на

{ // помилки

printf("Cannot open %s\n",argv[1]); // Повідомлення про помилку

return 0; // Завершення програми

}

if((fout=fopen("res.asm","w+"))==NULL) // Створення файлу з перевіркою на

{ // помилки

printf("Cannot create res.asm\n"); // Повідомлення про помилку

return 0; // Завершення програми

}

for(i=0;!feof(fin);i++)

in[i]=fgetc(fin); // Читання вхідного файлу в масив

filesize=i; // Визначення розміру масиву

fprintf(fout,".386 \n.387 \nstack segment use16 \ndb 256 dup(?) \nstack ends \n");

fprintf(fout,"data segment use16 \nconv\t dt 0 \n"); // Початок програми

for(i=0;i<filesize;i++) // Ініціалізація змінних

{

e=found=0;

while(isalpha(in[i])) // Читання ідентифікатора

{

found=1;

var[e++]=in[i++];

}

if(found) // Обробка зчитаного ідентифікатора

{

var[e]=0;

new_entry=1;

for(k=0;k<max_id;k++) // Пошук в таблиці ідентифікаторів

if(strcmp(id[k],var)==0)

{

КП.КС-05.00.00.000 ПЗ | Арк.

16

Зм. | Арк. | № докум | Підпис | Дата

new_entry=0; // Ідентифікатор знайдений в таблиці

break;

}

if(new_entry) // Якщо є новий ідентифікатор

{

fprintf(fout,"%s\t dw ",var); // Запис директиви у вихідний файл

for(e=0;var[e]!=0;e++)

id[max_id][e]=var[e]; // Запис ідентифікатора в таблицю

id[max_id++][e]=0;

if(in[i]=='=') // Якщо є присвоєння

{

d=1;

i++;

if(in[i]=='-')

fprintf(fout,"%c",in[i++]); // Вставка мінуса

for(e=0;in[i]!=0x0A;i++) // Перевірка присвоєння значення числа

{

if(!isdigit(in[i]))

{

d=0; // Це присвоєння значення змінної

break;

}

var[e++]=in[i]; // Читання значення числа

}

var[e]=0;

if(d)

fprintf(fout,"%s",var); // Присвоєння значення числа

else

fprintf(fout,"0"); // Ініціалізація змінної нулем

}

КП.КС-05.00.00.000 ПЗ | Арк.

17

Зм. | Арк. | № докум | Підпис | Дата

else

fprintf(fout,"0"); // Ініціалізація змінної нулем

}

}

}

fprintf(fout,"data ends\n code segment use16\n assume cs:code, ds:data, ss:stack\n main:\tmov ax,data \n\tmov ds,ax \n\tmov ax,stack \n\tmov ss,ax \n\tmov sp,256 \n\txor si,si \n"); // Початок сегменту програми

for(i=0;i<filesize;i++) // Трансляція тексту

{

if(strcmp(in+i,"input")==0) // Якщо знайдена конструкція input

{

i+=6; // Перехід до позиції ідентифікатора

for(e=0;in[i]!=0x0A;i++,e++)

var[e]=in[i]; // Читання ідентифікатора

var[e]=0;

fprintf(fout,"\tlea bx,[si+%s] \n\tcall input \n",var);

continue; // Запис конструкції в файл

}

if(strcmp(in+i,"print")==0) // Якщо знайдена конструкція print

{

i+=6; // Перехід до позиції ідентифікатора

for(e=0;in[i]!=0x0A;i++,e++)

var[e]=in[i]; // Читання ідентифікатора

var[e]=0;

fprintf(fout,"\tlea bx,[si+%s] \n\tcall print \n",var);

continue; // Запис конструкції в файл

}

for(e=0;isalpha(in[i])&&in[i]!='='&&in[i]!=0x0A&&in[i]!=0x0D;i++,e++)

var[e]=in[i]; // Читання ідентифікатора

КП.КС-05.00.00.000 ПЗ


Сторінки: 1 2 3 4