Передача параметров блоком (Masm) - Assembler

Узнай цену своей работы

Формулировка задачи:

Сформировать новый массив и внести в него все повторяющиеся элементы исходного массива по одному разу. Начал делать вот так:
.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
Но столкнулся с проблемой - если элемент повторяется >1 раза, скопировать его нужно только 1й раз. Набросал алгоритм (смесь с++ и асм), а с реализацией затрудняюсь...

Решение задачи: «Передача параметров блоком (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

Объяснение кода листинга программы

  1. .586 - это метаданные, указывающие на модель процессора, совместимую с 80586.
  2. .model flat, stdcall - это метаданные, указывающие на модель памяти и модель вызова функций.
  3. option casemap :none - это метаданные, контролирующие сопоставление регистров в строках.
  4. include \masm32\include\windows.inc - это метаданные, включающие заголовочный файл Windows API.
  5. include \masm32\include\masm32.inc - это метаданные, включающие заголовочный файл MASM32.
  6. include \masm32\include\msvcrt.inc - это метаданные, включающие заголовочный файл стандартных библиотек CRT.
  7. include \masm32\macros\macros.asm - это метаданные, включающие файл с макросами MASM32.
  8. includelib \masm32\lib\masm32.lib - это метаданные, подключающие библиотеку MASM32.
  9. includelib \masm32\lib\msvcrt.lib - это метаданные, подключающие библиотеку стандартных библиотек CRT.
  10. .data - это раздел, в котором хранятся переменные данных.
  11. arr dd 1,2,7,2,3,10,5,6,7,6,11,15 - это переменная данных, представляющая собой двумерный массив.
  12. len_a = ($ - arr)/4 - это вычисление длины массива.
  13. tpt db '%d', 13,10,0 - это строковая константа, используемая для вывода.
  14. tpte db '%d repeated elements.', 13,10,0 - это строковая константа, используемая для вывода.
  15. .code - это раздел, в котором хранятся исполняемые инструкции.
  16. start: - это метка начала программы.
  17. mov ecx, len_a - это инструкция по перемещению переменной len_a в регистр ecx.
  18. xor edx, edx - это инструкция по перемещению нуля в регистр edx.
  19. lea esi, arr - это инструкция по перемещению адреса массива arr в регистр esi.
  20. lodsd - это инструкция загрузки двойного слова из памяти в регистр eax.
  21. mov edi, esi - это инструкция по перемещению адреса массива arr в регистр edi.
  22. push ecx - это инструкция по сохранению регистра ecx в стеке.
  23. repne scasd - это инструкция по сравнению и замене двойных слов в памяти.
  24. jcxz m1 - это инструкция по переходу к метке m1, если ecx равен нулю.
  25. inc edx - это инструкция по увеличению значения регистра edx на единицу.
  26. push edx - это инструкция по сохранению регистра edx в стеке.
  27. invoke crt_printf, ADDR tpt, eax - это инструкция по вызовоу функции crt_printf с аргументами tpt и eax.
  28. pop edx - это инструкция по восстановлению значения регистра edx из стека.
  29. m1: pop ecx - это инструкция по восстановлению значения регистра ecx из стека.
  30. loop c1 - это инструкция по повторению цикла, пока ecx больше нуля.
  31. gtfo: invoke crt_printf, ADDR tpte, edx - это инструкция по вызовоу функции crt_printf с аргументами tpte и edx.
  32. invoke crt_exit, 0 - это инструкция по вызовоу функции crt_exit с аргументом 0.
  33. end start - это метка конца программы.

ИИ поможет Вам:


  • решить любую задачу по программированию
  • объяснить код
  • расставить комментарии в коде
  • и т.д
Попробуйте бесплатно

Оцени полезность:

12   голосов , оценка 4.333 из 5