Как найти минимальный элемент массива ассемблер

У меня уже есть готовая программа, которая находит минимальное значение в массиве, но проблема вся в том, что если я поменяю в массиве допустим цифру 7 на -100, то у меня все равно выведет -15. Не могу понять в чем проблема и как ее пофиксить.

.486
.model flat, stdcall
option casemap: none
include /masm32/include/windows.inc
include /masm32/include/user32.inc
include /masm32/include/kernel32.inc
includelib /masm32/lib/user32.lib
includelib /masm32/lib/kernel32.lib
include /masm32/macros/macros.asm
uselib masm32, comctl32, ws2_32
include <masm32includewindows.inc>
include <masm32includekernel32.inc>
includelib <masm32libkernel32.lib>
include <masm32includeuser32.inc>
includelib <masm32libuser32.lib>
include <masm32includemasm32.inc>
includelib <masm32libmasm32.lib>
include <masm32includedebug.inc>
includelib <masm32libdebug.lib>

.data

msg_title db "Title", 0
A DB 1h
x dd -15,1,2,3,4,5,6,7,8,9,10,11
n dd 12
buffer db 128 dup(?)
format db "%d",0
min dd ?
imin dd ?

.code

start:

mov ecx, n
dec ecx
xor edi, edi ; указатель на 1-й элемент, принятый за начальный минимум 
mov esi, 1 ; указатель на 2-й элемент (его индекс 1)

cycle:
    mov eax, x[esi]
    cmp eax, x[esi]
    jge @next
    mov edi, esi
@next:
    inc esi
    loop cycle
    mov imin, edi ; запись индекса минимального элемента
    mov eax, x[edi]
    mov min, eax ; запись индекса минимального элемента

PrintDec imin
PrintLine
PrintDec min

invoke ExitProcess, 0
end start

390 / 323 / 19

Регистрация: 26.05.2009

Сообщений: 2,696

1

В массиве найти минимальный и максимальный элемент

11.09.2012, 02:25. Показов 54138. Ответов 22


Студворк — интернет-сервис помощи студентам

Здравствуйте! На ассемблере последний раз писал что-то ещё на 1-м курсе универа и всё забыл за неимением практики. А тут пришла знакомая и попросила помочь с заданием.
Если не сложно, помогите мне. Буду очень благодарен.
Задание:
1) в массиве найти минимальный и максимальный элемент;

Добавлено через 8 минут
Желательна максимальная простота кода и, если не сложно, комментарии, т.к. это потом ей ещё защищать.



0



Troll_Face

608 / 406 / 8

Регистрация: 26.04.2012

Сообщений: 2,065

12.09.2012, 19:34

2

Assembler
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
mov si, offset array
mov cx, array_len
xor bx, bx                     ;в bh - максимум, в bl - минимум...
@1: 
     lodsb 
     cmp al, bh
     jg max
     cmp al, bl
     jl min
     jmp @@1
min: 
     and bl, al
     jmp @@1
max:
    and bh, al
@@1:
    loop @1

не тестировал, сразу говорю, но вроде так…

Добавлено через 22 часа 34 минуты
body90, пардон))) хотел повыпендриваться)))

Assembler
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
mov si, offset array
mov cx, array_len
xor bx, bx                     ;в bh - максимум, в bl - минимум...
@1: 
     lodsb 
     cmp al, bh
     jg max
     cmp al, bl
     jl min
     jmp @@1
min: 
     mov bl, al
     jmp @@1
max:
    mov bh, al
@@1:
    loop @1



3



390 / 323 / 19

Регистрация: 26.05.2009

Сообщений: 2,696

12.09.2012, 21:42

 [ТС]

3

И не понимаю, что делает “lodsb”. Можете пояснить, для чего эта команда в этом коде?



0



390 / 323 / 19

Регистрация: 26.05.2009

Сообщений: 2,696

12.09.2012, 21:57

 [ТС]

4

Вот что у меня получается:

Миниатюры

В массиве найти минимальный и максимальный элемент
 



0



390 / 323 / 19

Регистрация: 26.05.2009

Сообщений: 2,696

12.09.2012, 22:11

 [ТС]

5

В архиве то, что я написал. Запускаю по run.bat.



0



766 / 310 / 11

Регистрация: 27.05.2011

Сообщений: 703

12.09.2012, 22:14

6

body90, ты наверно думаешь, что представленный код является полным?
это только выполнение твоего задания(поиск min,max), оформление здесь отсутствует, как допишешь его, так и сможешь проверить..
возми ту же элементарную программку – Hello World, впиши туда то что тебе написали и всё..
только вот ещё одно, результата на экране ты не увидишь, пока не допишешь вывод, либо ч/з отладчик..



2



body90

390 / 323 / 19

Регистрация: 26.05.2009

Сообщений: 2,696

12.09.2012, 22:25

 [ТС]

7

Assembler
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
.model   small
.data
array dd 1,2,3,4,5
mov si, offset array
mov cx, 5
xor bx, bx                     ;в bh - максимум, в bl - минимум...
.code
main:
@1: 
     lodsb 
     cmp al, bh ;сравнение al и bh
     jg max
     cmp al, bl
     jl min
     jmp @@1
min: 
     mov bl, al
     jmp @@1
max:
    mov bh, al
@@1:
    loop @1
end main
end

Написал так. Компиллируется без ошибок, но вот когда запускаю *.exe – выскакивает ошибка с кнопкой “Закрыть”. Я что-то неправильно сделал?

Цитата
Сообщение от zzzyyyxxx
Посмотреть сообщение

только вот ещё одно, результата на экране ты не увидишь, пока не допишешь вывод, либо ч/з отладчик..

А как вывод делать?



0



766 / 310 / 11

Регистрация: 27.05.2011

Сообщений: 703

12.09.2012, 22:28

8

ну у тебя часть кода находится в данных, перенести надо..
по поводу вывода – https://www.cyberforum.ru/asse… 54461.html, выбирай, что душе угодно..



1



body90

390 / 323 / 19

Регистрация: 26.05.2009

Сообщений: 2,696

13.09.2012, 02:16

 [ТС]

9

.data должен быть пустым?

Добавлено через 36 минут
Так тоже вылетает с ошибкой:

Assembler
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
.model   small
.data
.code
array dd 1,2,3,4,5
mov si, offset array
mov cx, 5
xor bx, bx                     ;в bh - максимум, в bl - минимум...
@1: 
     lodsb 
     cmp al, bh ;сравнение al и bh
     jg max
     cmp al, bl ;сравнение al и bl
     jl min
     jmp @@1
min: 
     mov bl, al
     jmp @@1
max:
    mov bh, al
@@1:
    loop @1 ; переход на следующий элемент массива
end

Добавлено через 25 минут
Подскажите, пожалуйста, что я ещё неправильно делаю. А то мне сегодня её уже надо отдать…



0



390 / 323 / 19

Регистрация: 26.05.2009

Сообщений: 2,696

13.09.2012, 02:49

 [ТС]

10

Вот как оно вылетает (первое изображение) после нажатия F9 в TLINK.exe.
На втором изображении то, что видно на консоли, если я сделаю это же через DosBox. После этого курсор просто мигает и не реагирует ни на какие нажатия.

Миниатюры

В массиве найти минимальный и максимальный элемент
 

В массиве найти минимальный и максимальный элемент
 



0



390 / 323 / 19

Регистрация: 26.05.2009

Сообщений: 2,696

13.09.2012, 05:31

 [ТС]

11

Почему-то мне кажется, что приложение просто зацикливается.

Добавлено через 2 часа 18 минут
И с этим разобрался, но в bh и bl ложатся числа, которых даже нет в массиве. Посмотрел в Turbo Debuggere в окне Wotches. Что может быть не так?



0



Ушел с форума

Автор FAQ

15873 / 7450 / 1008

Регистрация: 11.11.2010

Сообщений: 13,427

13.09.2012, 05:47

12

body90, опять используется массив двойных слов вместо массива байтов, и массив array убери из секции code в секцию data
будь внимательнее и думай головой



1



body90

390 / 323 / 19

Регистрация: 26.05.2009

Сообщений: 2,696

13.09.2012, 11:08

 [ТС]

13

Mikl___, сделал так, как Вы сказали. Совсем теперь по “циклу” один раз стало проходить.

Assembler
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
Title   Laba
;=====================================
StackSG segment ; Stack segment
    dw  1024    dup (?)
StackSG Ends
;=====================================
DataSG  Segment; Data segment
DataSG Ends
;=====================================
CodeSG  Segment ; Code segment
    assume  ss:StackSG,cs:CodeSG,ds:DataSG
 
BEGIN:
array db 7,2,10,4,26
mov si, offset array
mov cx, 5
xor bx, bx
@1: 
     lodsb 
     cmp al, bh
     jg max
     cmp al, bl
     jl min
     jmp @@1
min: 
     mov bl, al
     jmp @@1
max:
    mov bh, al
@@1:
    loop @1
mov     ah,4ch
int 21h
CodeSG  Ends
END BEGIN

Добавлено через 21 минуту
А тут точно можно использовать bh и bl? Я не могу понять их поведения. Они по прежнему получают значения, которых вообще нет в массиве. Ещё и меняют значение, когда выполняется последний кусок кода

Assembler
1
2
3
4
mov     ah,4ch
int 21h
CodeSG  Ends
END BEGIN

хотя обращений к ним нет. Может я чего-то не понимаю.

Добавлено через 25 секунд
Может кто-то скомпиллировать мой код и сказать что не так?



0



Ушел с форума

Автор FAQ

15873 / 7450 / 1008

Регистрация: 11.11.2010

Сообщений: 13,427

13.09.2012, 11:40

14

body90, тебе же сказали — помести array в сегмент данных!



1



body90

390 / 323 / 19

Регистрация: 26.05.2009

Сообщений: 2,696

13.09.2012, 11:46

 [ТС]

15

Всё равно результат тот же.

Assembler
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
Title   Laba
;=====================================
StackSG segment ; Stack segment
    dw  1024    dup (?)
StackSG Ends
;=====================================
DataSG  Segment; Data segment
array db 7,2,10,4,26
DataSG Ends
;=====================================
CodeSG  Segment ; Code segment
    assume  ss:StackSG,cs:CodeSG,ds:DataSG
 
BEGIN:
mov si, offset array
mov cx, 5
xor bx, bx
@1: 
     lodsb 
     cmp al, bh
     jg max
     cmp al, bl
     jl min
     jmp @@1
min: 
     mov bl, al
     jmp @@1
max:
    mov bh, al
@@1:
    loop @1
mov     ah,4ch
int 21h
CodeSG  Ends
END BEGIN

В момент до выполнения строки

Assembler
1
mov     ah,4ch

bh = 32
bl = 159



1



390 / 323 / 19

Регистрация: 26.05.2009

Сообщений: 2,696

13.09.2012, 11:47

 [ТС]

16

Вот скрин.

Миниатюры

В массиве найти минимальный и максимальный элемент
 



1



Mikl___

Ушел с форума

Автор FAQ

15873 / 7450 / 1008

Регистрация: 11.11.2010

Сообщений: 13,427

13.09.2012, 11:50

17

должно быть вот так

Assembler
1
2
3
4
5
BEGIN: mov ax,DataSG
mov ds,ax
mov si, offset array
mov cx, 5
xor bx, bx



2



390 / 323 / 19

Регистрация: 26.05.2009

Сообщений: 2,696

13.09.2012, 11:56

 [ТС]

18

bh работает, а в bl теперь всё время лежит 0, хотя в массиве минимальный элемент = 2.



0



Ушел с форума

Автор FAQ

15873 / 7450 / 1008

Регистрация: 11.11.2010

Сообщений: 13,427

13.09.2012, 12:03

19

body90, естественно, потому что изначально BL=0, а ноль всегда меньше двух
поставь вместо xor bx,bx команду mov bx,7Fh и всё заработает



1



body90

390 / 323 / 19

Регистрация: 26.05.2009

Сообщений: 2,696

13.09.2012, 12:03

 [ТС]

20

Не знаю правильно ли, но вышел из ситуации так:

Assembler
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
Title   Laba
;=====================================
StackSG segment ; Stack segment
    dw  1024    dup (?)
StackSG Ends
;=====================================
DataSG  Segment; Data segment
    array db 7,2,10,4,26
DataSG Ends
;=====================================
CodeSG  Segment ; Code segment
    assume  ss:StackSG,cs:CodeSG,ds:DataSG
 
BEGIN:
mov ax, DataSG
mov ds, ax
mov si, offset array
mov cx, 5
xor bx, bx
mov bl, al
@1: 
     lodsb 
     cmp al, bh
     jg max
     cmp al, bl
     jl min
     jmp @@1
min: 
     mov bl, al
     jmp @@1
max:
    mov bh, al
@@1:
    loop @1
mov     ah,4ch
int 21h
CodeSG  Ends
END BEGIN



0



Собственно программа готова, но выводит ошибки. Ругается на len. Прошу помочь исправить программу. Заранее спасибо!

.386
.model  flat,stdcall
option  casemap:none
include d:masm32includekernel32.inc
include d:masm32includemsvcrt.inc
include d:masm32macrosmacros.asm
 
includelib d:masm32libmsvcrt.lib
includelib d:masm32libkernel32.lib
 
.data 
array db 15,-100,50,0
len equ $ - array
min db ?
imin dw ?
tpt db      'Result Min = al',0
 
.stack 100h 
.code 
 
start: 
    mov ax,@data 
    mov ds,ax 
    mov cx,len 
    dec cx 
    xor di,di           ; указатель на 1-й элемент, принятый за начальный минимум 
    mov si,1            ; указатель на 2 элемент (его индекс 1) 
cycle: 
    mov al,array[si] 
    cmp al,array[di] 
    jge next 
    mov di,si 
next: 
    inc si 
    loop cycle 
    mov imin,di         ; запись индекса минимального элемента 
    mov al,array[di] 
    mov min,al          ; запись значения минимального элемента 
;   ...
    mov ah,4ch 
    int 21h 
    invoke  crt_printf, ADDR tpt, min
        invoke  ExitProcess, 0
    
    end start

Для начала разработаем блок-схему

1 Находим максималтный элемент

2 Находим минимальный элемент

3 Находим их разность

Теперь работаем :

data

caption db “prog”,0

text db “результат = %d”,0

tr db 100 DUP(?)

n dd 5,3,8,1,4,2,6,4,11,7

min dd 0

max dd 0

code

main:

mov esi,0

mov ecx,10

mov eax,[n+esi]

mov [min],eax

l1:

mov eax,[n+esi]

cmp eax,[min]

jnl m1

mov [min],eax

m1:

add esi,4

loop l1

invoke wsprintfA, addr tr, addr text,[min] ;находим минимум

invoke MessageBox, 0, addr tr, addr caption, 0

mov esi,0

mov ecx,10

mov eax,[n+esi]

mov [max],eax

l2:

mov eax,[n+esi]

cmp eax,[max]

jng m2

mov [max],eax

m2:

add esi,4

loop l2

invoke wsprintfA, addr tr, addr text,[max]

invoke MessageBox, 0, addr tr, addr caption, 0 ;находим максимум

mov eax,[min]

mov ebx,[max]

sub eax,ebx

invoke wsprintfA, addr tr, addr text,[min]

invoke MessageBox, 0, addr tr, addr caption, 0 ;находим их разность

invoke ExitProcess,0

end main

Вот и все.


Форум программистов Vingrad

Модераторы: Poseidon

Поиск:

Ответ в темуСоздание новой темы
Создание опроса
> [TASM] Нахождение минимального элемента массива, Минимальный элемент массива 

V

   

Опции темы

avlzll
Дата 8.4.2009, 19:00 (ссылка)
| (нет голосов)
Загрузка ... Загрузка …




Быстрая цитата

Цитата

Новичок

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

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

Всем добрый день. Застопорился на простенькой задаче.

Необходимо найти минимальный элемент массива. ( Y = min (X) )

Начало есть.

Код

Ideal
P386n
Model Small

Dataseg
    n equ 10    
    x dw 0, 9, 3, 2, -4, 19, -19, 07, 7, -9    
    y dw ?

Codeseg

Start:
    mov    ax, @DATA
    mov    ds, ax
    mov    cx, n
    xor    ax, ax
    lea    bx, [x]

Дальше ясно, что надо организовать цикл, используя метки, cmp и условные переходы. Вопрос в том, как? 

Заранее спасибо за любую помощь.

Это сообщение отредактировал(а) avlzll – 8.4.2009, 19:04

PM MAIL   Вверх
Akina
Дата 8.4.2009, 19:10 (ссылка)
| (нет голосов)
Загрузка ... Загрузка …




Быстрая цитата

Цитата

Советчик
****

Профиль
Группа: Модератор
Сообщений: 20561
Регистрация: 8.4.2004
Где: Зеленоград

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

Код

mov ax, @DATA
mov ds, ax
mov cx, n
lea si,x
dec si
cld
lodsw
mov y,ax
label0:
lodsw
cmp ax,y
jae label1
mov y,ax
label1:
rep label0

PS. Проверять лень.

——————–

 О(б)суждение моих действий – в соответствующей теме, пожалуйста. Или в РМ. И высшая инстанция – Администрация форума.

PM MAIL WWW ICQ Jabber   Вверх
avlzll
Дата 8.4.2009, 19:32 (ссылка)
| (нет голосов)
Загрузка ... Загрузка …




Быстрая цитата

Цитата

Новичок

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

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

Спасибо за оперативный ответ smile Но в таком виде, увы, не компилируется.

Код

Ideal
P386n
Model Small

Dataseg
    n equ 10    
    x dw 0, 9, 3, 2, -4, 19, -19, 07, 7, -9    
    y dw ?

Codeseg

Start:
    mov ax, @DATA
    mov ds, ax
    mov cx, n
    lea si,x
    dec si
    cld
    lodsw
    mov y,ax
label0:
    lodsw
    cmp ax, y
    jae label1
    mov y, ax
label1:
    rep label0

    mov ax, 4c00h
    int 21h

Stack 100
end start

В листинге вот что
Т.е. ошибки в строках 16, 20, 23, 25 и 27.

Код

      1                     Ideal
      2                     P386n
      3        0000             Model Small
      4
      5        0000             Dataseg
      6          = 10                 n equ 10
      7        0000  0000 0009 0003 0002 +         x dw 0, 9, 3, 2, -4, 19, -19, 07, 7, -9
      8          FFFC 0013 FFED 0007 +
      9          0007 FFF7
     10        0014  ????                 y dw ?
     11
     12        0016             Codeseg
     13
     14        0000             Start:
     15        0000  B8 0000s             mov ax, @DATA
     16        0003  8E D8                 mov ds, ax
     17        0005  B9 000A             mov cx, n
     18        0008  BE 0000r             lea si,x
*Warning* lab2.ASM(16) Pointer expression needs    brackets
     19        000B  4E                 dec si
     20        000C  FC                 cld
     21        000D  AD                 lodsw
     22        000E  A3 0014r             mov y,ax
*Warning* lab2.ASM(20) Pointer expression needs    brackets
     23        0011                 label0:
     24        0011  AD                 lodsw
     25        0012  3B 06    0014r             cmp ax,y
*Warning* lab2.ASM(23) Pointer expression needs    brackets
     26        0016  73 05    90 90             jae label1
     27        001A  A3 0014r             mov y,ax
*Warning* lab2.ASM(25) Pointer expression needs    brackets
     28        001D                 label1:
     29        001D  F3>                 rep label0
**Error** lab2.ASM(27) Illegal instruction
     30        001E  B8 4C00             mov ax, 4c00h
     31        0021  CD 21                 int 21h
     32
     33        0023             Stack 100
     34                     end start

PM MAIL   Вверх
Akina
Дата 8.4.2009, 19:43 (ссылка)
| (нет голосов)
Загрузка ... Загрузка …




Быстрая цитата

Цитата

Советчик
****

Профиль
Группа: Модератор
Сообщений: 20561
Регистрация: 8.4.2004
Где: Зеленоград

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

Да, вместо rep label0 должно быть loop label0. А уж остальное сам поправь, что надо сделать – очевидно…
PS. А результат-то выводить собираешься?

——————–

 О(б)суждение моих действий – в соответствующей теме, пожалуйста. Или в РМ. И высшая инстанция – Администрация форума.

PM MAIL WWW ICQ Jabber   Вверх
avlzll
Дата 8.4.2009, 20:00 (ссылка)
| (нет голосов)
Загрузка ... Загрузка …




Быстрая цитата

Цитата

Новичок

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

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

Да, остальные места тоже поправил и скомпилилось. Спасибо за помощь!
Готовое решение выглядит так (мб кому в будущем пригодится 🙂 .

Код

Ideal
P386n
Model Small

Dataseg
    n equ 10    
    x dw 0, 9, 3, 2, -4, 19, -19, 07, 7, -9    
    y dw ?

Codeseg

Start:
    mov ax, @DATA
    mov ds, ax
    mov cx, n
    lea si, [x]
    dec si
    cld
    lodsw
    mov [y], ax
label0:
    lodsw
    cmp ax, [y]
    jae label1
    mov [y], ax
label1:
    loop label0

    mov ax, 4c00h
    int 21h

Stack 100
end start

Насчет вывода на экран — как получится, ибо это всего лишь вторая в жизни программа на Асме 🙂 Пока с трудом идет.

PM MAIL   Вверх



















Ответ в темуСоздание новой темы
Создание опроса
Правила форума “Центр помощи”

ВНИМАНИЕ! Прежде чем создавать темы, или писать сообщения в данный раздел, ознакомьтесь, пожалуйста, с Правилами форума и конкретно этого раздела.
Несоблюдение правил может повлечь за собой самые строгие меры от закрытия/удаления темы до бана пользователя!

  • Название темы должно отражать её суть! (Не следует добавлять туда слова “помогите”, “срочно” и т.п.)
  • При создании темы, первым делом в квадратных скобках укажите область, из которой исходит вопрос (язык, дисциплина, диплом). Пример: [C++].
  • В названии темы не нужно указывать происхождение задачи (например “школьная задача”, “задача из учебника” и т.п.), не нужно указывать ее сложность (“простая задача”, “легкий вопрос” и т.п.). Все это можно писать в тексте самой задачи.
  • Если Вы ошиблись при вводе названия темы, отправьте письмо любому из модераторов раздела (через личные сообщения или report).
  • Для подсветки кода пользуйтесь тегами [code][/code] (выделяйте код и нажимаете на кнопку “Код”). Не забывайте выбирать при этом соответствующий язык.
  • Помните: один топик – один вопрос!
  • В данном разделе запрещено поднимать темы, т.е. при отсутствии ответов на Ваш вопрос добавлять новые ответы к теме, тем самым поднимая тему на верх списка.
  • Если вы хотите, чтобы вашу проблему решили при помощи определенного алгоритма, то не забудьте описать его!
  • Если вопрос решён, то воспользуйтесь ссылкой “Пометить как решённый”, которая находится под кнопками создания темы или специальным флажком при ответе.

Более подробно с правилами данного раздела Вы можете ознакомится в этой теме.


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

 

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

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