Перенести в начало массива все положительные элементы - Assembler
Формулировка задачи:
Доброго времени суток. Нужно перенести в начало массива все положительные элементы
Мой код:
Выводит 3, -1, -2, 4, 5, 6, 7, 8, 9, 7
А должен, естественно, 3, 4, 5, 6, 7, 8, 9, 7, -1, -2
Что я делаю не так, где ошибка?
Благодарю.
include "D:\prog\fasmw\INCLUDE\win32ax.inc" .data ar dd -1, -2, 3, 4, 5, 6, 7, 8, 9, 7 caption1 db "Массив = %d %d %d %d %d %d %d %d %d %d ", 0 tr db 50 DUP(?) .code main: mov esi, 0 ;; для проверки знака mov ebx, -4 ;; нулевой элемент массива mov edx, 36 ;; для проверки конца массива l1: add ebx, 4 cmp [ar+ebx] , esi ;; esi == 0, проверки больше 0 jl m1 jmp l1 m1: mov eax, ebx ;; для временного использования lm1: cmp [ar+eax+8] , edx ;; edx == 36, проверка конца массива jl continue jmp exit continue: cmp [ar+eax+4], 0 ;; находим потом положительные для свапа jg swapp jmp m2 swapp: mov edi, [ar+ebx] ;; edi = [temp] mov edx, [ar+eax+4] mov [ar+ebx], edx mov [ar+eax+4], edi jmp l1 m2: add eax, 4 jmp lm1 exit: invoke wsprintfA, addr tr, addr caption1, [ar+0], [ar+4], [ar+8], [ar+12], [ar+16], [ar+20], [ar+24], [ar+28], [ar+32], [ar+36] invoke MessageBoxA, 0, addr tr, addr caption1, 0 invoke ExitProcess, 0 .end main
Решение задачи: «Перенести в начало массива все положительные элементы»
textual
Листинг программы
format PE GUI 4.0 entry Start include 'win32a.inc' section '.text' code readable executable Start: cld ; направление mov esi,ar ; адрес начала массива mov ecx,Cycle ; циклов @@: ; пихаем всё в стек lodsd push eax loop @r mov edi,ar ; адрес начала массива mov ecx,Cycle ; циклов mov esi,Adr_ar_end ; смещение на конец массива sortir: ; сортируем из стека pop eax cmp eax,0 jb minus stosd ; в цепочку с начала jmp @f minus: mov [esi],eax ; в цепочку с конца sub esi,4 ; адрес конца +4 @@: loop sortir invoke wsprintfA, tr, caption1, [ar+0], [ar+4], [ar+8], [ar+12], [ar+16], [ar+20], [ar+24], [ar+28], [ar+32], [ar+36] invoke MessageBoxA, 0,tr,Title, 0 invoke ExitProcess, 0 section '.data' data readable writeable ar dd -1, -2, 3, 4, 5, 6, 7, 8, 9, 7 Cycle = ($-ar)/4 ; число циклов Adr_ar_end = ar+Cycle*4-4 ; адрес последнего элемента Title db 'Заголовок',0 caption1 db "Массив = %d %d %d %d %d %d %d %d %d %d ", 0 tr db 50 DUP(?)
Объяснение кода листинга программы
Предположительно данный код выполняет следующие действия:
- Задаёт направление (cld).
- Инициализирует переменные (mov esi,ar; mov ecx,Cycle).
- В цикле (while) сортирует массив по возрастанию (lodsd; push eax; loop @r).
- Выводит отсортированный массив на экран (invoke wsprintfA, tr, caption1, [ar+0], [ar+4], [ar+8], [ar+12], [ar+16], [ar+20], [ar+24], [ar+28], [ar+32], [ar+36]; invoke MessageBoxA, 0,tr,Title, 0; invoke ExitProcess, 0).
- Задаёт адрес начала массива (mov edi,ar), количество циклов (mov ecx,Cycle) и смещение на конец массива (mov esi,Adr_ar_end).
- В цикле (while) сортирует массив по убыванию (pop eax; cmp eax,0; jb minus; stosd; sub esi,4; loop sortir).
- Выводит отсортированный массив на экран (invoke wsprintfA, tr, caption1, [ar+0], [ar+4], [ar+8], [ar+12], [ar+16], [ar+20], [ar+24], [ar+28], [ar+32], [ar+36]; invoke MessageBoxA, 0,tr,Title, 0; invoke ExitProcess, 0).
- Инициализирует переменные (Title db 'Заголовок',0; caption1 db
Массив = %d %d %d %d %d %d %d %d %d %d
, 0; tr db 50 DUP(?)). - Задаёт начальное значение переменной Cycle (Cycle = ($-ar)/4).
- Вычисляет адрес последнего элемента массива (Adr_ar_end = ar+Cycle*4-4).
ИИ поможет Вам:
- решить любую задачу по программированию
- объяснить код
- расставить комментарии в коде
- и т.д