Передача параметров блоком (Masm) - Assembler
Формулировка задачи:
Сформировать новый массив и внести в него все повторяющиеся элементы исходного массива по одному разу.
Начал делать вот так:
Но столкнулся с проблемой - если элемент повторяется >1 раза, скопировать его нужно только 1й раз.
Набросал алгоритм (смесь с++ и асм), а с реализацией затрудняюсь...
.686 ;Система команд процессора 686 .MODEL FLAT,stdcall;Модель памяти плоская, стандартный вызов процедуры option casemap:none;Режим при котором заглавные и строчные буквы различаются ; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤ .XLIST include \masm32\include\masm32rt.inc ; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤ comment * ----------------------------------------------------- Условие задачи: Сформировать новый массив и внести в него все повторяющиеся элементы исходного массива по одному разу. ----------------------------------------------------- * .LIST .DATA Bl_a label byte na dd 11 ;[ebx+4] na1 dd 0 a1 dd 12 dup(?) ;[ebx+esi+8] a dd -10,1,6,2,6,8,-1,3,-10,-7,2 ;[ebx+esi+56] .code start: ; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤ mov ebx,offset Bl_a call Copy_El exit ; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤ Copy_El proc push ebp mov ebp,esp push eax ;Сохраняем регистры, которые используем push ebx push ecx push edx push esi push edi mov ebx,[ebp+4] ;В ebx адрес блока параметров и одновременно адрес первого параметра блока mov edx,[ebx+esi+52] ;Адрес для копирования mov esi,0 ;позиция текущего элемента массива относительно его начала mov eax,[ebx+esi+8] ;за сравниваемый элемент принимаем первый элемент mov ecx,[ebx+4] ;Количество элементов массива c1: cmp eax,[ebx+esi+8]; je m2 mov eax,[ebx+esi+8] ;Новый сравниваемый элемент m1: add esi,4 loop c1 m2: ;Копирование в массив а1 mov [edi],eax add edi,4 exit: pop esi pop edx pop ecx pop ebx pop eax pop ebp ret Copy_El endp ; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤ end start
Решение задачи: «Передача параметров блоком (Masm)»
textual
Листинг программы
.586 .model flat, stdcall option casemap :none include \masm32\include\windows.inc include \masm32\include\masm32.inc include \masm32\include\msvcrt.inc include \masm32\macros\macros.asm includelib \masm32\lib\masm32.lib includelib \masm32\lib\msvcrt.lib .data arr dd 1,2,7,2,3,10,5,6,7,6,11,15 len_a = ($ - arr)/4 tpt db '%d', 13,10,0 tpte db '%d repeated elements.', 13,10,0 .code start: mov ecx, len_a xor edx, edx lea esi, arr c1: lodsd mov edi, esi push ecx repne scasd jcxz m1 inc edx push edx ; ECX и EDX загаживаются безвозмездно invoke crt_printf, ADDR tpt, eax pop edx m1: pop ecx loop c1 gtfo: invoke crt_printf, ADDR tpte, edx invoke crt_exit, 0 end start
Объяснение кода листинга программы
- .586 - это метаданные, указывающие на модель процессора, совместимую с 80586.
- .model flat, stdcall - это метаданные, указывающие на модель памяти и модель вызова функций.
- option casemap :none - это метаданные, контролирующие сопоставление регистров в строках.
- include \masm32\include\windows.inc - это метаданные, включающие заголовочный файл Windows API.
- include \masm32\include\masm32.inc - это метаданные, включающие заголовочный файл MASM32.
- include \masm32\include\msvcrt.inc - это метаданные, включающие заголовочный файл стандартных библиотек CRT.
- include \masm32\macros\macros.asm - это метаданные, включающие файл с макросами MASM32.
- includelib \masm32\lib\masm32.lib - это метаданные, подключающие библиотеку MASM32.
- includelib \masm32\lib\msvcrt.lib - это метаданные, подключающие библиотеку стандартных библиотек CRT.
- .data - это раздел, в котором хранятся переменные данных.
- arr dd 1,2,7,2,3,10,5,6,7,6,11,15 - это переменная данных, представляющая собой двумерный массив.
- len_a = ($ - arr)/4 - это вычисление длины массива.
- tpt db '%d', 13,10,0 - это строковая константа, используемая для вывода.
- tpte db '%d repeated elements.', 13,10,0 - это строковая константа, используемая для вывода.
- .code - это раздел, в котором хранятся исполняемые инструкции.
- start: - это метка начала программы.
- mov ecx, len_a - это инструкция по перемещению переменной len_a в регистр ecx.
- xor edx, edx - это инструкция по перемещению нуля в регистр edx.
- lea esi, arr - это инструкция по перемещению адреса массива arr в регистр esi.
- lodsd - это инструкция загрузки двойного слова из памяти в регистр eax.
- mov edi, esi - это инструкция по перемещению адреса массива arr в регистр edi.
- push ecx - это инструкция по сохранению регистра ecx в стеке.
- repne scasd - это инструкция по сравнению и замене двойных слов в памяти.
- jcxz m1 - это инструкция по переходу к метке m1, если ecx равен нулю.
- inc edx - это инструкция по увеличению значения регистра edx на единицу.
- push edx - это инструкция по сохранению регистра edx в стеке.
- invoke crt_printf, ADDR tpt, eax - это инструкция по вызовоу функции crt_printf с аргументами tpt и eax.
- pop edx - это инструкция по восстановлению значения регистра edx из стека.
- m1: pop ecx - это инструкция по восстановлению значения регистра ecx из стека.
- loop c1 - это инструкция по повторению цикла, пока ecx больше нуля.
- gtfo: invoke crt_printf, ADDR tpte, edx - это инструкция по вызовоу функции crt_printf с аргументами tpte и edx.
- invoke crt_exit, 0 - это инструкция по вызовоу функции crt_exit с аргументом 0.
- end start - это метка конца программы.
ИИ поможет Вам:
- решить любую задачу по программированию
- объяснить код
- расставить комментарии в коде
- и т.д