Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Удаление элемента, массив, Нужна помощь в удалении элемента  
:(
    Опции темы
droha
  Дата 5.10.2010, 20:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 4
Регистрация: 4.10.2009

Репутация: нет
Всего: нет



Помогите, плиз, с таким заданием:
Найти минимальный нечетный элемент и удалить его из массива.
Нужно сделать - передачей параметров через стек.
Минимальный нечетный я нашел:
Код

sseg segment
     db 64 dup(0)
sseg ends
dseg segment
     x dw 4,8,69,3,1,5,88
     nx dw 7
     minx dw ?
     y dw 25,9,13,4,87
     ny dw 5
     miny dw ?
dseg ends
cseg segment
     assume cs:cseg, ss:sseg, ds:dseg
;------------------
main proc far
     push ds
     xor ax,ax
     push ax
     mov ax,dseg
     mov ds,ax
;---------------
     lea ax,x
     push ax
     lea ax,minx
     push ax
     push nx
     call min_n
     lea ax,y
     push ax
     lea ax,miny
     push ax
     push ny
     call min_n
     ret
main endp
;-------------------
min_n proc near
     push bp
     mov bp,sp
     push ax cx dx si di
     mov si,[bp+8]
     mov cx,[bp+4]
     mov bx,si
d:
     test [si],1
     jz t
     mov ax,[si]
     jmp c
t:
     add si,2
     loop d
c:
     test [si],1
     jz m1
     cmp ax,[si]
     jl m1
     mov dx,[si]
     mov ax,dx
     mov bx,si
m1:
     add si,2
     loop c
     mov di,[bp+6]
     mov [di],dx
     pop di si dx cx ax
     pop bp
     ret 6

min_n endp
;-----------------------
cseg ends
end main      


Помогите с удалением.

P.S. Заранее огромнейшее спасибо!!!



PM MAIL   Вверх
iff
Дата 9.10.2010, 18:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Администратор
**


Профиль
Группа: Участник
Сообщений: 949
Регистрация: 23.3.2007

Репутация: 4
Всего: 16



Код

sseg segment para stack ;*
     db 64 dup(0)
sseg ends
dseg segment
     x dw 4,8,69,3,1,5,88
     nx dw 7
     minx dw ?
     y dw 25,9,13,4,87
     ny dw 5
     miny dw ?
dseg ends
cseg segment
     assume cs:cseg, ss:sseg, ds:dseg, es:dseg ;*
;------------------
main proc far
     push ds
     xor ax,ax
     push ax
     mov ax,dseg
     mov ds,ax
     mov es, ax   ;!!!
;---------------
     lea ax,x
     push ax
     lea ax,minx
     push ax
     push nx
     call min_n
     lea ax,y
     push ax
     lea ax,miny
     push ax
     push ny
     call min_n

     lea ax,x   ;!!!
     push ax    ;!!!
     push minx  ;!!!
     lea ax, nx ;!!!
     push ax    ;!!!
     call del_n ;!!!
     lea ax,y   ;!!!
     push ax    ;!!!
     push miny  ;!!!
     lea ax, ny ;!!!
     push ax    ;!!!
     call del_n ;!!!

     ret
main endp
;-------------------
min_n proc near
     push bp
     mov bp,sp
     push ax cx dx si di
     mov si,[bp+8]
     mov cx,[bp+4]
     mov bx,si
d:
     test [si],1
     jz t
     mov ax,[si]
     jmp c
t:
     add si,2
     loop d
c:
     test [si],1
     jz m1
     cmp ax,[si]
     jl m1
     mov dx,[si]
     mov ax,dx
     mov bx,si
m1:
     add si,2
     loop c
     mov di,[bp+6]
     mov [di],dx
     pop di si dx cx ax
     pop bp
     ret 6

min_n endp
;-----------------------

del_n proc near            ;!!!
     push bp               ;!!!
     mov bp, sp            ;!!!
     push ax bx cx di si   ;!!!
     pushf                 ;!!!
     mov ax, [bp+6]        ;!!!
     mov bx, [bp+4]        ;!!!
     mov cx, [bx]          ;!!!
     mov di, [bp+8]        ;!!!
     cld                   ;!!!
     repne scasw           ;!!!
     mov si, di            ;!!!
     dec di                ;!!!
     dec di                ;!!!
     mov cx, [bx]          ;!!!
     shl cx, 1             ;!!!
     sub cx, si            ;!!!
     rep movsb             ;!!!
     dec word ptr [bx]     ;!!!
     popf                  ;!!!
     pop si di cx bx ax bp ;!!!
     ret 6                 ;!!!
del_n endp                 ;!!!
;-----------------------

cseg ends
end main      

Знаком ";!!!" я пометил те строки, которые я добавил, а знаком ";*" - те, которые изменил. Изменения косаются строк "sseg segment para stack" и "assume cs:cseg, ss:sseg, ds:dseg, es:dseg". В первой я добавил параметр para stack чтобы компилятор понимал, что это сегмент стека. Во второй я дописал es:dseg т.к. в моей подпрограмме используется регистр es.

Это сообщение отредактировал(а) iff - 9.10.2010, 18:40


--------------------
DOS... Синей пеленой экран заполнил чистый DOS 
Мышь... Стала вдруг квадратной, потеряла форму мышь... 
Я разбил окно, девяностопятое мастдайное окно, 
И поставил DOS, и тогда увидел: Это счастье, — вот оно.  
PM MAIL WWW   Вверх
droha
Дата 10.10.2010, 12:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 4
Регистрация: 4.10.2009

Репутация: нет
Всего: нет



Спасибо огромное!!! Но есть вопросик! 
1. В первом массиве удаляется минимум, но следующее число дублируется 2 раза, как это исправить?
2. А во втором массиве происходит зацикливание?
Заранее спасибо за ответ!
PM MAIL   Вверх
iff
Дата 10.10.2010, 19:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Администратор
**


Профиль
Группа: Участник
Сообщений: 949
Регистрация: 23.3.2007

Репутация: 4
Всего: 16



1. При отладке кода вам действительно может показаться что последнее число дублируется, но это не так. Что значит удалить элемент из массива?

Итак, синим цветом и жирно я выделил сам массив (адрес - ds:0000), зеленым - его длину (адрес - ds:000E), а красным минимум, элемент со значением которого будет удален (адрес - ds:0010). Все остальное, черного цвета, - мусор. Исходный массив соответственно содержит 0004 0008 0045 0003 0001 0005 0058

Шаг 1.
Пусть имеется вот такие данные (дамп после выполнения подпрограммы поиска минимума):
ds:0000   0004 0008 0045 0003
ds:0008   0001 0005 0058 0007
ds:0010   0001 0019 0009 000D

(Выполнение моей подпрограммы):
Шаг 2.
Найдем индекс элемента содержащего 1 инструкцией repne scasw.
Шаг 3.
Сместим (копируем инструкцией rep movsb) элементы, стоящее правее удаляемого, влево на слово. Получим:
ds:0000   0004 0008 0045 0003
ds:0008   0005 0058 0058 0007
ds:0010   0001 0019 0009 000D

Шаг 4.
Уменьшим длину массива на 1 элемент. Т.е. уменьшем значение переменной nx (или ny) на 1. Получим:
ds:0000   0004 0008 0045 0003
ds:0008   0005 0058  0058 0006
ds:0010   0001 0019 0009 000D

Т.е. раньше мы имели массив 0004 0008 0045 0003 0001 0005 0058, а теперь он содержит 0004 0008 0045 0003 0005 0058.

Для большей наглядности просмотрите этот анимированный рисунок:
user posted image

2. Моя подпрограмма в принцепе не может перейти в бесконечный цикл. Но из-за оштбки действительно, цикл смещения элементов массива повторяется слишком много раз. Для исправления ошибки добавь после 104 строки строку add cx, [bp+8]. Т.е. у вас должно получиться:
Код

sseg segment para stack ;!!!
     db 64 dup(0)
sseg ends
dseg segment
     x dw 4,8,69,3,1,5,88
     nx dw 7
     minx dw ?
     y dw 25,9,13,4,87
     ny dw 5
     miny dw ?
dseg ends
cseg segment
     assume cs:cseg, ss:sseg, ds:dseg, es:dseg ;!!!
;------------------
main proc far
     push ds
     xor ax,ax
     push ax
     mov ax,dseg
     mov ds,ax
     mov es, ax   ;!!!
;---------------
mov cx, 10
a10:

     lea ax,x
     push ax
     lea ax,minx
     push ax
     push nx
     call min_n
     lea ax,y
     push ax
     lea ax,miny
     push ax
     push ny
     call min_n

     lea ax,x   ;!!!
     push ax    ;!!!
     push minx  ;!!!
     lea ax, nx ;!!!
     push ax    ;!!!
     call del_n ;!!!
     lea ax,y   ;!!!
     push ax    ;!!!
     push miny  ;!!!
     lea ax, ny ;!!!
     push ax    ;!!!
     call del_n ;!!!

loop a10

     ret
main endp
;-------------------
min_n proc near
     push bp
     mov bp,sp
     push ax cx dx si di
     mov si,[bp+8]
     mov cx,[bp+4]
     mov bx,si
d:
     test [si],1
     jz t
     mov ax,[si]
     jmp c
t:
     add si,2
     loop d
c:
     test [si],1
     jz m1
     cmp ax,[si]
     jl m1
     mov dx,[si]
     mov ax,dx
     mov bx,si
m1:
     add si,2
     loop c
     mov di,[bp+6]
     mov [di],dx
     pop di si dx cx ax
     pop bp
     ret 6

min_n endp
;-----------------------

del_n proc near            ;!!!
     push bp               ;!!!
     mov bp, sp            ;!!!
     push ax bx cx di si   ;!!!
     pushf                 ;!!!
     mov ax, [bp+6]        ;!!!
     mov bx, [bp+4]        ;!!!
     mov cx, [bx]          ;!!!
     mov di, [bp+8]        ;!!!
     cld                   ;!!!
     repne scasw           ;!!!
     mov si, di            ;!!!
     dec di                ;!!!
     dec di                ;!!!
     mov cx, [bx]          ;!!!
     shl cx, 1             ;!!!
     add cx, [bp+8]        ;!!!!!!!!!!
     sub cx, si            ;!!!
     rep movsb             ;!!!
     dec word ptr [bx]     ;!!!
     popf                  ;!!!
     pop si di cx bx ax bp ;!!!
     ret 6                 ;!!!
del_n endp                 ;!!!
;-----------------------

cseg ends
end main      



Это сообщение отредактировал(а) iff - 10.10.2010, 20:26


--------------------
DOS... Синей пеленой экран заполнил чистый DOS 
Мышь... Стала вдруг квадратной, потеряла форму мышь... 
Я разбил окно, девяностопятое мастдайное окно, 
И поставил DOS, и тогда увидел: Это счастье, — вот оно.  
PM MAIL WWW   Вверх
droha
Дата 10.10.2010, 20:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 4
Регистрация: 4.10.2009

Репутация: нет
Всего: нет



Все, вроде разобрался! Огромнейшее спасибо за помощь!!!!!
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Asm для начинающих"
MAKCim
  • Проставьте несколько ключевых слов темы, чтобы её можно было легче найти.
  • Не забывайте пользоваться кнопкой КОД.
  • Телепатов на форуме нет! Задавайте чёткий, конкретный и полный вопрос. Указывайте полностью ошибки компилятора и компоновщика.
  • Новое сообщение должно иметь прямое отношение к разделу форума. Флуд, флейм, оффтопик запрещены.
  • Категорически запрещается обсуждение вареза, "кряков", взлома программ и т.д.

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, MAKCim.

 
 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Asm для начинающих | Следующая тема »


 




[ Время генерации скрипта: 0.0712 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.