Задание выполняется на Visual C++ 2003 — 2008 с использованием assembler вставок. В этом задании необходимо выполнить соответствующие преобразования над строкой или строками.

/*
Задание выполняется на Visual C++ 2003 — 2008 с использованием
ассемблерных вставок. В этом задании необходимо выполнить соответствующие
преобразования над строкой или строками. Решение задачи необходимо оформить
в виде одной или несколько подпрограмм, содержащих ассемблерные вставки. Как
правило, в каждом задании по одной или двум входным строкам надо
получить выходную строку, удовлетворяющую определенным условиям, причем
под выходную строку необходимо выделить память и сделать это надо внутри
ассемблерной вставки. Кроме того, программа должна иметь «дружелюбный»
интерфейс (например, предлагать выполнить повторное тестирование). Ввод
данных из файла не требуется, хотя приветствуется. Ввод/вывод с
консоли выполнять с помощью функций printf и scanf, вызов которых
тоже должен происходить внутри ассемблерных вставок.
Указать те символы, которые есть и в первой и во второй строке.
*/

#include
#include

void main()
{
setlocale(0,»rus»);
const int N = 255;
char* res;
char* dys1 = «введите первую строку\n»;
char* dys2 = «\nвведите вторую строку\n»;
char* dys3 =»\nЕще? Enter — да, ESC — выход\n»;
char* err = «\nпамяти не дали»;
char* p = «pause»;
char* clear = «cls»;
char* ns = «Данные строки не имеют общих символов»;
char* str1;
char* str2;
__asm
{
// выделение памяти и считывание первой строки
BEGIN: ; главный цикл

mov eax,clear
push eax
call dword ptr system
add esp,4
mov eax,dys1 ;
push eax
call dword ptr printf ; вывели dys1
add esp,4 ; почистили стек

mov eax,N ; положили в eax размер строки
push eax ; положили размер в стек
call dword ptr malloc ; выделяем память под первую строку
add esp,4 ; чистим стек
cmp eax,0 ; проверяем, выделилась ли память
je MEMORY_ER ; В случае не выделения памяти сообщаем об ошибке
mov str1,eax ; если памяти дали, то записываем адрес первой строки
push eax ; опять положили в стек адрес первой строки
call dword ptr gets ; считали строку
add esp,4 ; почистили стек

mov eax,dys2
push eax
call dword ptr printf
add esp,4

mov eax,N ; положили в eax размер строки
push eax ; положили размер в стек
call dword ptr malloc ; выделяем память под вторую строку
add esp,4 ; чистим стек
cmp eax,0 ; проверяем, выделилась ли память
je MEMORY_ER ; В случае не выделения памяти сообщаем об ошибке
mov str2,eax ; если памяти дали, то записываем адрес первой строки
push eax ; опять положили в стек адрес первой строки
call dword ptr gets ; считали строку
add esp,4 ; почистили стек
mov edx,str2 ; запомнили адрес первой строки, чтоб лишний раз не лазить в память
mov ebx,str1 ; запомнили адрес первой строки, чтоб лишний раз не лазить в память
// в еbx — адрес первой строки
// в edx — адрес второй строки
// поиск
mov edx,str2 ; запомнили адрес первой строки, чтоб лишний раз не лазить в память
mov ebx,str1 ; запомнили адрес первой строки, чтоб лишний раз не лазить в память

xor eax,eax ; обнуляем eax
// теперь нам надо посчитать количество совпавших элементов
xor edi,edi ; в edi количество совпавших элементов

START: ; внешний цикл

xor esi,esi ; esi — текущий счетчик
mov cl,[ebx][eax] ; положили в cl первый символ первой строки
inc eax ; увеличили счетчик
cmp cl,0 ; проверка конца строки
je NEW_RES ; ушли на выделение памяти под результат

START2:
mov ch,[edx][esi] ; положили в ch следующий символ
cmp ch,0 ; проверка конца строки
je END ; ушли в обнуление текущего счетчика

cmp cl,ch ; сравнили символы
je FOUND ; если символы совпали — говорим нашли
inc esi ; увеличили текущий счетчик
jmp START2

END:
jmp START ; возвращаемся в главный цикл

FOUND:
inc edi ; увеличили счетчик совпавших символов
jmp START ; ушли в главный цикл

NEW_RES:
cmp edi,0
je NOT_SOVP
inc edi ; увеличили размер результатата под 0 символ
push edi ; положили в eax размер результата
call dword ptr malloc ; выделили память под результат
add esp,4 ; почистили стек
cmp eax,0 ; проверили выделение памяти
je MEMORY_ER
mov res,eax ; записали адрес результата

jmp RES
NOT_SOVP:
mov eax,ns
push eax
call dword ptr printf
add esp,4
mov eax,res
xor eax,eax
xchg res,eax
jmp REPEAT

RES:

mov edx,str2 ; запомнили адрес первой строки, чтоб лишний раз не лазить в память
mov ebx,str1 ; запомнили адрес первой строки, чтоб лишний раз не лазить в память

// в еbx — адрес первой строки
// в edx — адрес второй строки
xor ecx,ecx
xor eax,eax
xor edi,edi

START3: ; внешний цикл

xor esi,esi ; esi — текущий индекс второй строки
mov cl,[ebx][eax] ; положили в cl первый символ первой строки
inc eax ; увеличили счетчик
cmp cl,0 ; проверка конца строки
je PRINT_RES ; ушли на выделение памяти под результат

START4:
mov ch,[edx][esi] ; положили в ch следующий символ
cmp ch,0 ; проверка конца строки
je END1 ; ушли в обнуление текущего счетчика

cmp cl,ch ; сравнили символы
je FOUND1 ; если символы совпали — говорим нашли
inc esi ; увеличили текущий счетчик
jmp START4

END1:
jmp START3 ; возвращаемся в главный цикл

FOUND1:

xchg esi,res
//push esi
//mov esi,res
mov [esi+edi], cl ; на место res[edi] кладём совпавший символ
xchg esi,res
//pop esi
inc edi ; увеличили счетчик совпавших символов
jmp START3 ; ушли в главный цикл

PRINT_RES:
//inc edi
//xor eax,eax
mov esi,res
xor cl,cl
mov [esi+edi],cl

push esi
call dword ptr printf
add esp,4

REPEAT:
mov eax,str1
push eax
call dword ptr free
add esp,4
mov eax,str2
push eax
call dword ptr free
add esp,4
mov eax,res

cmp eax,0

je NEXT
push eax
call dword ptr free
add esp,4

NEXT:

mov eax,dys3
push eax
call dword ptr printf
add esp,4

call dword ptr getch ; смотрим, что нажали
cmp eax,27
je EXIT
cmp eax,13
je BEGIN
jmp BEGIN

MEMORY_ER:
mov eax,err
push eax
call dword ptr printf
add esp,4
mov eax,p
push eax
call dword ptr system
add esp,4
jmp REPEAT
EXIT:
}

}

Реклама

Добавить комментарий

Этот сайт использует Akismet для борьбы со спамом. Узнайте как обрабатываются ваши данные комментариев.