Как найти максимальное значение ассемблер

Есть задание. Необходимо найти значение максимального элемента в массиве. Элементы массива должны иметь тип WORD (2 байта). В первом элементе массива должно хранить количество элементов массива −1. То есть оттуда мы должны считать количество чисел, перейти на адрес второй ячейки массива, и начиная с числа по этому адресу уже сравнивать.

Написал следующий код:

section .text
   global _start 
    
_start: 
        
   mov  eax, 3    ; mov eax, [x]
   mov  ebx,0      ; EBX будет хранить максимальное значение
   mov  ecx, x    ; ECX будет указывать на текущий элемент для выполнения операции сравнения
   add ecx, 2 
 
top:  cmp ebx, [ecx]
   JNS l1
   mov ebx, [ecx]
   l1: add  ecx, 2      ; перемещаем указатель на следующий элемент
   dec  eax        ; выполняем декремент счётчика
   jnz  top        ; если счётчиком не является 0, то тогда выполняем цикл ещё раз
 
done: 
 
   add   ebx, '0'
   mov  [max], ebx ; готово, сохраняем результат в переменной sum
 
display:
 
   mov  edx, 2      ; длина сообщения
   mov  ecx, max   ; сообщение для написания
   mov  ebx, 1     ; файловый дескриптор (stdout)
   mov  eax, 4     ; номер системного вызова (sys_write)
   int  0x80       ; вызов ядра
    
   mov  eax, 1     ; номер системного вызова (sys_exit)
   int  0x80       ; вызов ядра
 
section .data
global x
x:
   dw  3
   dw  2
   dw  4
   dw  3
 
max: 
   dw  0

Компилирую в Linux через консоль, компиляция проходит, но результат выводит неправильный. Кроме того, ему не нравится синтаксис(segmentation fault)

mov eax, [x]

Если кто разбирается в ассемблере, помогите, пожалуйста. Где я ошибся?

390 / 323 / 19

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

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

1

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

11.09.2012, 02:25. Показов 54471. Ответов 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

15888 / 7462 / 1012

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

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

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

15888 / 7462 / 1012

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

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

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

15888 / 7462 / 1012

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

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

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

15888 / 7462 / 1012

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

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

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



Improve Article

Save Article

Like Article

  • Read
  • Discuss
  • Improve Article

    Save Article

    Like Article

    Problem – Determine largest number in an array of n elements. Value of n is stored at address 2050 and array starts from address 2051. Result is stored at address 3050. Starting address of program is taken as 2000. 

    Example: 

    Algorithm:

    1. We are taking first element of array in A
    2. Comparing A with other elements of array, if A is smaller then store that element in A otherwise compare with next element
    3. The value of A is the answer

    Program:

    Memory Address Mnemonics Comment
    2000 LXI H 2050 H←20, L←50
    2003 MOV C, M C←M
    2004 DCR C C←C-01
    2005 INX H HL←HL+0001
    2006 MOV A, M A←M
    2007 INX H HL←HL+0001
    2008 CMP M A-M
    2009 JNC 200D If Carry Flag=0, goto 200D
    200C MOV A, M A←M
    200D DCR C C←C-1
    200E JNZ 2007 If Zero Flag=0, goto 2007
    2011 STA 3050 A→3050
    2014 HLT  

    Explanation:

     Registers used: A, H, L, C

    1. LXI 2050 assigns 20 to H and 50 to L
    2. MOV C, M copies content of memory (specified by HL register pair) to C (this is used as a counter)
    3. DCR C decrements value of C by 1
    4. INX H increases value of HL by 1. This is done to visit next memory location
    5. MOV A, M copies content of memory (specified by HL register pair) to A
    6. INX H increases value of HL by 1. This is done to visit next memory location
    7. CMP M compares A and M by subtracting M from A. Carry flag and sign flag becomes set if A-M is negative
    8. JNC 200D jumps program counter to 200D if carry flag = 0
    9. MOV A, M copies content of memory (specified by HL register pair) to A
    10. DCR C decrements value of C by 1
    11. JNZ 2007 jumps program counter to 2007 if zero flag = 0
    12. STA 3050 stores value of A at 3050 memory location
    13. HLT stops executing the program and halts any further execution

    Advantages of finding the largest number in an array:

    1. It is a simple and straightforward task that can be easily implemented in any programming language.
       
    2. It is a common operation used in many algorithms and applications, such as finding the maximum value in a data set or determining the winner of a game.
       
    3. It is a fast operation that can be completed in O(n) time complexity, where n is the number of elements in the array.
       

    Disadvantages of finding the largest number in an array:

    1. If the array is unsorted, finding the largest number requires iterating through the entire array, which can be inefficient for very large arrays.
       
    2. If multiple elements in the array have the same maximum value, finding only one of them requires additional logic or iterations, which can add complexity to the algorithm.
       
    3. If the array is very large and memory is limited, storing the entire array in memory may not be feasible, which could require a more complex solution such as sorting the array in smaller parts.

    Last Updated :
    07 May, 2023

    Like Article

    Save Article

    Вечер добрый, господа! Задача: поиск максимального элемента в массиве и вывод его. Знаю, что тема уже заезженная и много тем о ней, но код не работает) Я тут пробовал написать, но чет не очень у меня не шибко работает) Может кто поможет новичку исправить код? Использую FASM.

    org 100H
     
      mov si, -1
      mov bl, 0      ; хранится значение max
     
    start:
      inc si
      cmp si, 9
      je exit
     
      cmp [mas + si], bl
      jg zamena   ; если эл. массива больше регистра bl (max), то вызываем замену
      jmp start
    
    exit:
      mov ah, 02h
      mov dl, bl       ; выводим наш максимальный эл
      int 21h
     
      mov ah, 0
      int 16h
     
      mov ax, 4C00h
      int 21h
      ret
    
    zamena:
      mov bl, [mas + si]       ; заменяем bl(max) на эл. массива
      loop start
    
    mas db 1,2,3,4,5,6,7,8,9,5

    24th
    Мар

    Posted by obzor under assembler, c/c++

    Помогите найти минимальное и максимальное значения.
    На вход идет массив цифр из 5 элементов , нужно найти min и max в Ассемблере и вывести в C++.

    ura_111

    Вот вроде забацал (используя пример с интернета):

    Код:

    
    #include "stdafx.h"
    #include <iostream>
    using namespace std;
    
    int _tmain(int argc, _TCHAR* argv[])
    {
    	int max, min; //ИЗМЕНЕНО: вместо max2, переменная min; вместо multiplication, переменная summa
    	int a[5] = { 1, 7, 0, 2, 3};
    	_asm
    	{
    		; max element one
    			cld  //ДОБАВЛЕНО: для установки направления поиска от меньшего адреса к большему
    			//в твоем примере из-за отсутствия этой строки могли быть ошибки при исполнении
    
    			//---эта часть - поиск максимума---
    			lea esi, a //записываешь адрес массива в регистра ESI
    			mov ebx, dword ptr[esi]  //читаешь значение по адресу указываемому регистром ESI, в регистр EBX
    			mov ecx, 5 //записываешь значение 10 (количество элементов массива) в регистр ECX
    		M1:
    		lodsd  //читаем значение по указываемому регистром ESI, в регистр EAX, и увеличиваем ESI на 4
    			cmp eax, ebx  //сравниваешь содержимое двух регистров
    			jle M2  //условный переход: переходить если первый регистр (EAX) <= второму регистру (EBX)
    			mov ebx, eax //сохраняешь большее значение из регистра EAX в регистре EBX
    		M2 :
    		loop M1 //цикл: уменьшение ECX на 1, переход на метку M1 если ECX не равен нулю
    			mov max, ebx //сохраняем найденный максимум в переменной max
    			//---эта часть - поиск максимума---
    
    			//---эта часть - поиск минимума---
    			lea esi, a  //записываешь адрес массива в регистра ESI
    			mov ebx, dword ptr[esi]  //читаешь значение по адресу указываемому регистром ESI, в регистр EBX
    			mov ecx, 5  //записываешь значение 10 (количество элементов массива) в регистр ECX
    		M3:
    		lodsd  //читаем значение по указываемому регистром ESI, в регистр EAX, и увеличиваем ESI на 4
    			cmp eax, ebx  //сравниваешь содержимое двух регистров
    			jge M4  //ИЗМЕНЕНО: условный переход: переходить если первый регистр (EAX) >= второму регистру (EBX)
    			//            cmp eax, max  //УДАЛИТЬ
    			//            je M4  //УДАЛИТЬ
    			mov ebx, eax  //сохраняешь меньшее значение из регистра EAX в регистре EBX
    		M4 :
    		loop M3 //цикл: уменьшение ECX на 1, переход на метку M3 если ECX не равен нулю
    			mov min, ebx  //ИЗМЕНИТЬ: сохраняем минимум в переменной min
    			//---эта часть - поиск минимума---
    	}
    	cout << "Max: " << max << " Min : " << min << endl;
    
    	cin >> max; // чтобы консоль не закрывалась
    	return 0;
    }
    
    

    R71MT

    Поиск минимального..
    Элементы массива размером DWORD (32-бит):

    Код:

    
    _asm { 
          mov   ecx,5          ; ЕСХ = всего элементов
          lea   esi,mas        ; ESI = адрес массива
          mov   ebx,[esi]      ; EBX = первый элемент
    find: lodsd                ; ЕАХ = очередной элемент массива
          cmp   eax,ebx        ; сравниваем..
          jae   miss           ; переход, если больше
          xchg  ebx,eax        ; иначе: обменять местами
    miss: Loop  find           ; промотать ЕСХ-раз..
          mov   [min],ebx      ; запомнить мин. в переменной
         }
    
    

    Мановар

    Примажусь к славе. Только будет lea esi,a

    Код:

    
    #include "stdafx.h"
    #include <iostream>
    
    int main()
    {
    	int max, min;
    	int a[5] = { 11, 7, 5, 2, 3 };
    	_asm
    	{
    		mov   ecx, 5 // ЕСХ = всего элементов
    		lea   esi, a // ESI = адрес массива
    		mov   ebx, [esi]// EBX = первый элемент
    		find : lodsd // ЕАХ = очередной элемент массива
    			   cmp   eax, ebx // сравниваем..
    			   jae   miss // переход, если больше
    			   xchg  ebx, eax //иначе: обменять местами
    			   miss : Loop  find // промотать ЕСХ - раз..
    					  mov [min], ebx // запомнить мин.в переменной
    	}
    	std::cout << "Min. element = " << min << std::endl;
    	system("pause");
    }
    
    

    тема на форуме

    Похожие статьи

    • Смена текста при нажатии на кнопку
    • Функция min

    Понравилась статья? Поделить с друзьями:
  • При сборке мебели повредили мебель как исправить
  • Как найти деньги на квартиру в москве
  • Как найти большую сторону треугольника по углам
  • Как можно найти свой потерянный айфон
  • Как найти горшок с золотом